ManyToMany 和 OneToOne 关系的 Jpa 标准

Jpa Criteria for ManyToMany and OneToOne relationships

我有 3 个 POJO 类 - Link、Link详细信息和标签。 Link 和 LinkDetails 之间的关系 - OneToOne,LinkDetails 和 Tag 之间的关系 - ManyToMany.

如何使用Jpa Criteria,查找具有指定标签名称的链接列表?

@Entity
public class Link extends AbstractEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String url;

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private LinkDetails linkDetails;
}

@Entity
public class LinkDetails extends AbstractEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;    

    @Column
    private String description;

    @JoinTable(name = "link_details_2_tag", joinColumns = { @JoinColumn(name = "link_details_id")}, inverseJoinColumns = { @JoinColumn(name = "tag_id") })
    @ManyToMany(targetEntity = Tag.class, fetch = FetchType.LAZY)
    private Set<Tag> tags = new TreeSet<Tag>();

}

@Entity
public class Tag extends AbstractEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;
}
@Override
public List<Link> getLinksByTag(String tag){

    CriteriaBuilder cBuilder = getEntityManager().getCriteriaBuilder();
    CriteriaQuery<Link> criteria = cBuilder.createQuery( Link.class );
    Root<Link> linkRoot = criteria.from( Link.class );
    Join<Link, LinkDetails> linkDetailsJoin = linkRoot.join(Link_.linkDetails);
    Join<LinkDetails, Tag> tagJoin = linkDetailsJoin.join(LinkDetails_.tags);
    criteria.select(linkRoot);
    criteria.where(cBuilder.equal(tagJoin.get(Tag_.name), tag));
    TypedQuery<Link> query = getEntityManager().createQuery(criteria);
    return query.getResultList();
}