JPA Criteria API 按字段嵌套实体列表查找

问题描述

我有 Certificate 类,其中包含 Tag 类列表(多对多),我必须找到包含某些 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();