JPA Criteria API 按字段嵌套实体列表查找
JPA Criteria API find by field nested list of entities
我有 Certificate
class 包含 Tag
class 的列表(多对多),我必须找到 Certificates
包含某些Tag
(按标签名称)
我正在使用 JPA Criteria API 但不能这样做..
@Entity
@Table(name = "gift_certificate")
public class Certificate {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
private BigDecimal price;
private Integer duration;
@Column(name = "create_date")
private LocalDateTime createDate;
@Column(name = "last_update_date")
private LocalDateTime lastUpdateDate;
@ManyToMany
@JoinTable(name = "gift_certificate_tag",
joinColumns = @JoinColumn(name = "tag_id"),
inverseJoinColumns = @JoinColumn(name = "gift_certificate_id")
)
private List<Tag> tags;
getters and setters and other code...
.....
@Entity
@Table(name = "tag")
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
getters and setters and other code...
我试过这样做,但出现异常 IllegalStateException: Illegal attempt to dereference path source [null.tags] of basic type
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Certificate> query = cb.createQuery(Certificate.class);
Root<Certificate> certificates = query.from(Certificate.class);
certificates.fetch("tags", JoinType.LEFT);
query.select(certificates).distinct(true);
query.where(cb.like(certificates.get("tags").get("name"), params.getTag()));
return entityManager.createQuery(query).getResultList();
我做到了!
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Certificate> criteriaQuery = cb.createQuery(Certificate.class);
Root<Certificate> certificates = criteriaQuery.from(Certificate.class);
Join<Certificate, Tag> tags = certificates.join("tags", JoinType.LEFT);
criteriaQuery = criteriaQuery.distinct(true).where(cb.like(tags.get("name"), params.getTag()));
return entityManager.createQuery(criteriaQuery).getResultList();
我有 Certificate
class 包含 Tag
class 的列表(多对多),我必须找到 Certificates
包含某些Tag
(按标签名称)
我正在使用 JPA Criteria API 但不能这样做..
@Entity
@Table(name = "gift_certificate")
public class Certificate {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
private BigDecimal price;
private Integer duration;
@Column(name = "create_date")
private LocalDateTime createDate;
@Column(name = "last_update_date")
private LocalDateTime lastUpdateDate;
@ManyToMany
@JoinTable(name = "gift_certificate_tag",
joinColumns = @JoinColumn(name = "tag_id"),
inverseJoinColumns = @JoinColumn(name = "gift_certificate_id")
)
private List<Tag> tags;
getters and setters and other code...
.....
@Entity
@Table(name = "tag")
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
getters and setters and other code...
我试过这样做,但出现异常 IllegalStateException: Illegal attempt to dereference path source [null.tags] of basic type
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Certificate> query = cb.createQuery(Certificate.class);
Root<Certificate> certificates = query.from(Certificate.class);
certificates.fetch("tags", JoinType.LEFT);
query.select(certificates).distinct(true);
query.where(cb.like(certificates.get("tags").get("name"), params.getTag()));
return entityManager.createQuery(query).getResultList();
我做到了!
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Certificate> criteriaQuery = cb.createQuery(Certificate.class);
Root<Certificate> certificates = criteriaQuery.from(Certificate.class);
Join<Certificate, Tag> tags = certificates.join("tags", JoinType.LEFT);
criteriaQuery = criteriaQuery.distinct(true).where(cb.like(tags.get("name"), params.getTag()));
return entityManager.createQuery(criteriaQuery).getResultList();