Spring 引导数据 JPA 查询具有 @ManyToMany 集合的实体
Spring Boot Data JPA Querying an Entity with a Collection which has @ManyToMany
我有一个名为 Club 的实体,它与一个名为 Type 的实体具有 @ManytoMany 关系。这种类型有各种俱乐部标签,例如它是足球俱乐部还是游泳俱乐部。所以一个俱乐部可以有多种类型,也可以在俱乐部之间共享某种类型。当我想 select 一个俱乐部时,我还想显示与访问类型集合的俱乐部相关联的标签。我应该如何实现这一目标?
@Data
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Club {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 20)
private String name;
@Column(length = 20)
private String shortName;
@Column(length = 80)
private String description;
@Column(length = 50)
private String email;
private boolean status;
@Lob
private Blob logo;
@Lob
private Blob cover;
@Column(length = 50)
private String website;
private double longitude;
private double latitude;
@Column(length = 20)
private String registrationId;
@CreatedDate
@Temporal(TemporalType.DATE)
@Column(nullable = false, updatable = false)
private Date registrationDate;
@Temporal(TemporalType.DATE)
private Date lastActiveDate;
@OneToMany(mappedBy = "club")
private List<Favourite> favourites;
@ManyToMany
private List<Type> type;
@OneToOne(fetch = FetchType.LAZY)
private Address address;
}
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
public class Type {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 10)
private String tag;
@ManyToMany(mappedBy = "type")
private List<User> user;
@ManyToMany(mappedBy = "type")
private List<Club> club;
@CreatedDate
@Temporal(TemporalType.DATE)
@Column(nullable = false, updatable = false)
private Date createdDate;
}
在 ClubRespository.java 中,我正在尝试像这样访问类型集合的标记变量。
@Repository
public interface ClubRepository extends JpaRepository<Club, Integer> {
@Query("SELECT new com.service.payload.response.ClubSend(c.id, c.name, c.type.tag, c.shorName, c.description, c.email, c.logo, c.cover, c.longitude, c.latitude, c.address) FROM Club c JOIN c.type WHERE c.id=c.type.club.id")
List<Club> findAllClubs();
}
ClubSend 是一个 DTO class 我创建它是为了映射我想要显示的字段,但是当我这样做时,我收到了这个错误。
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: illegal attempt to dereference collection [club0_.id.type] with element property reference [tag] [SELECT new com.vayemo.mysponsor.service.payload.response.ClubSend(c.id, c.name, c.type.tag, c.shorName, c.description, c.email, c.logo, c.cover, c.longitude, c.latitude, c.address) FROM com.vayemo.mysponsor.service.model.Club c JOIN c.type WHERE c.id=c.type.club.id]
Caused by: org.hibernate.QueryException: illegal attempt to dereference collection [club0_.id.type] with element property reference [tag] [SELECT new com.vayemo.mysponsor.service.payload.response.ClubSend(c.id, c.name, c.type.tag, c.shorName, c.description, c.email, c.logo, c.cover, c.longitude, c.latitude, c.address) FROM com.vayemo.mysponsor.service.model.Club c JOIN c.type WHERE c.id=c.type.club.id]
Caused by: org.hibernate.QueryException: illegal attempt to dereference collection [club0_.id.type] with element property reference [tag]
您的问题是查询中的 c.type
是一个列表,因此无法取消引用 c.type.club
。如果要访问类型对象,则需要在连接期间为其提供别名(如 ... FROM Club c JOIN c.type t ...
),但据我所知,您的 where 子句隐含在 [=13 的声明中=]关系。如果您想了解更多详情,请查看 this Whosebug answer.
我有一个名为 Club 的实体,它与一个名为 Type 的实体具有 @ManytoMany 关系。这种类型有各种俱乐部标签,例如它是足球俱乐部还是游泳俱乐部。所以一个俱乐部可以有多种类型,也可以在俱乐部之间共享某种类型。当我想 select 一个俱乐部时,我还想显示与访问类型集合的俱乐部相关联的标签。我应该如何实现这一目标?
@Data
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Club {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 20)
private String name;
@Column(length = 20)
private String shortName;
@Column(length = 80)
private String description;
@Column(length = 50)
private String email;
private boolean status;
@Lob
private Blob logo;
@Lob
private Blob cover;
@Column(length = 50)
private String website;
private double longitude;
private double latitude;
@Column(length = 20)
private String registrationId;
@CreatedDate
@Temporal(TemporalType.DATE)
@Column(nullable = false, updatable = false)
private Date registrationDate;
@Temporal(TemporalType.DATE)
private Date lastActiveDate;
@OneToMany(mappedBy = "club")
private List<Favourite> favourites;
@ManyToMany
private List<Type> type;
@OneToOne(fetch = FetchType.LAZY)
private Address address;
}
@Entity
@Data
@EntityListeners(AuditingEntityListener.class)
public class Type {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(length = 10)
private String tag;
@ManyToMany(mappedBy = "type")
private List<User> user;
@ManyToMany(mappedBy = "type")
private List<Club> club;
@CreatedDate
@Temporal(TemporalType.DATE)
@Column(nullable = false, updatable = false)
private Date createdDate;
}
在 ClubRespository.java 中,我正在尝试像这样访问类型集合的标记变量。
@Repository
public interface ClubRepository extends JpaRepository<Club, Integer> {
@Query("SELECT new com.service.payload.response.ClubSend(c.id, c.name, c.type.tag, c.shorName, c.description, c.email, c.logo, c.cover, c.longitude, c.latitude, c.address) FROM Club c JOIN c.type WHERE c.id=c.type.club.id")
List<Club> findAllClubs();
}
ClubSend 是一个 DTO class 我创建它是为了映射我想要显示的字段,但是当我这样做时,我收到了这个错误。
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryException: illegal attempt to dereference collection [club0_.id.type] with element property reference [tag] [SELECT new com.vayemo.mysponsor.service.payload.response.ClubSend(c.id, c.name, c.type.tag, c.shorName, c.description, c.email, c.logo, c.cover, c.longitude, c.latitude, c.address) FROM com.vayemo.mysponsor.service.model.Club c JOIN c.type WHERE c.id=c.type.club.id]
Caused by: org.hibernate.QueryException: illegal attempt to dereference collection [club0_.id.type] with element property reference [tag] [SELECT new com.vayemo.mysponsor.service.payload.response.ClubSend(c.id, c.name, c.type.tag, c.shorName, c.description, c.email, c.logo, c.cover, c.longitude, c.latitude, c.address) FROM com.vayemo.mysponsor.service.model.Club c JOIN c.type WHERE c.id=c.type.club.id]
Caused by: org.hibernate.QueryException: illegal attempt to dereference collection [club0_.id.type] with element property reference [tag]
您的问题是查询中的 c.type
是一个列表,因此无法取消引用 c.type.club
。如果要访问类型对象,则需要在连接期间为其提供别名(如 ... FROM Club c JOIN c.type t ...
),但据我所知,您的 where 子句隐含在 [=13 的声明中=]关系。如果您想了解更多详情,请查看 this Whosebug answer.