Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jpa 查询在Criteria API中存在多对多关系_Jpa_Criteria Api - Fatal编程技术网

Jpa 查询在Criteria API中存在多对多关系

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 {

有两个具有多对多关系的实体类,我试图创建一个查询,该查询测试一个表中所有实体的任何关系的存在性。我被卡住了,因为似乎没有办法通过CriteriaAPI引用JoinTable

示例实体:

@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;