Jpa 查询在Criteria API中存在多对多关系
有两个具有多对多关系的实体类,我试图创建一个查询,该查询测试一个表中所有实体的任何关系的存在性。我被卡住了,因为似乎没有办法通过CriteriaAPI引用JoinTable 示例实体:Jpa 查询在Criteria API中存在多对多关系,jpa,criteria-api,Jpa,Criteria Api,有两个具有多对多关系的实体类,我试图创建一个查询,该查询测试一个表中所有实体的任何关系的存在性。我被卡住了,因为似乎没有办法通过CriteriaAPI引用JoinTable 示例实体: @Entity @Table(name="man") public class Man { @Id @GeneratedValue private Long id; } @Entity @Table(name="woman") public class Woman {
@Entity
@Table(name="man")
public class Man {
@Id
@GeneratedValue
private Long id;
}
@Entity
@Table(name="woman")
public class Woman {
@Id
@GeneratedValue
private Long id;
@ManyToMany
@JoinTable(
name="man_woman",
joinColumns=
@JoinColumn(name="woman_id", referencedColumnName="id"),
inverseJoinColumns=
@JoinColumn(name="man_id", referencedColumnName="id")
)
private Set<Man> men;
}
到目前为止,我提出的最佳方案如下:
CriteriaQuery<Tuple> criteriaQuery = criteriaBuilder.createTupleQuery();
Root<Man> from = criteriaQuery.from(Man.class);
Subquery<Long> subquery = criteriaQuery.subquery(Long.class);
Root<Woman> sub_from = subquery.from(Woman.class);
SetJoin<Woman, Man> setJoin = sub_from.join(Woman_.men);
subquery.select(sub_from.get(Woman_.id));
subquery.where(from.in(setJoin.get(Man_.id)));
criteriaQuery.multiselect(from.alias("man_entity"),
criteriaBuilder.selectCase()
.when(
criteriaBuilder.exists(subquery)
, true)
.otherwise(false)
.alias("knows_any_women")
);
return em.createQuery(criteriaQuery).getResultList()
我想这句话最终会被优化成我想要的那种——但是有没有办法让它从一开始就变得更简单呢?有一个class
关系
?然后,您可以选择“join”表,并可以在需要时为其添加额外的属性…好主意,谢谢!虽然如果这个场景出现在应用程序中的多种情况下,我很快就会被大量的关系类弄得乱七八糟。因此,如果有一种方法可以通过查询来实现这一点,将会更加方便。
CriteriaQuery<Tuple> criteriaQuery = criteriaBuilder.createTupleQuery();
Root<Man> from = criteriaQuery.from(Man.class);
Subquery<Long> subquery = criteriaQuery.subquery(Long.class);
Root<Woman> sub_from = subquery.from(Woman.class);
SetJoin<Woman, Man> setJoin = sub_from.join(Woman_.men);
subquery.select(sub_from.get(Woman_.id));
subquery.where(from.in(setJoin.get(Man_.id)));
criteriaQuery.multiselect(from.alias("man_entity"),
criteriaBuilder.selectCase()
.when(
criteriaBuilder.exists(subquery)
, true)
.otherwise(false)
.alias("knows_any_women")
);
return em.createQuery(criteriaQuery).getResultList()
select m.id,
case when exists(select w.id
from woman w
inner join man_woman mw on w.id = mw.woman_id
inner join man m2 on m2.id = mw.man_id
where m.id in (m2.id)
)
then 1 else 0
from man;