我有
@Entity
public class Entity0 implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
@OneToOne
private Entity1 entity1;
...
}
@Entity
public class Entity1 implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
@OneToMany
private List<Entity2> entity2s;
...
}
@Entity
public class Entity2 implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
@ManyToOne
private Entity3 entity3;
...
}
@Entity
public class Entity3 implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
@Basic
private String property0;
...
}
(其中...
代表无参数构造函数,带有所有参数的构造函数以及所有属性的getter和setter)我有以下工作查询,它适用于Hibernate 5.2.12.Final(JPA 2.1) :
Entity3 entity3 = new Entity3(1l, "some property value");
TypedQuery<Long> query = entityManager.createQuery(
"SELECT COUNT(e0) FROM Entity0 e0 LEFT JOIN e0.entity1 e1 "
+ "WHERE e0.entity1 != null "
+ "AND NOT EXISTS (SELECT e2 FROM e1.entity2s e2 LEFT OUTER JOIN e2.entity3 e3 WHERE e3.id = :someId)",
Long.class)
.setParameter("someId", entity3.getId());
//join is necessary in order to be able to access
//e0.entity1.entity2s because JPA isn't capable of
//accessing a reference of a reference
long retValue = query.getSingleResult();
现在,我想通过JPA Criteria API转换要执行的查询,但我似乎无法弄清楚如何在涉及属性的子查询中执行连接,因为我只找到{{1}并且Root.join
总是指由类表示的实体。这导致以下尝试:
Root
(只需要修复子查询)。
根据像JPA/Metamodel: Strange (inconsistent ?) example in Sun Docs这样的帖子(这解释了Oracle作者如此周到地在他们的教程中列出了不可能的例子,但这是另一个问题),那里有{{1}但是,事实并非如此。
我感兴趣的是JPA 2.2或(2.3如果已经有任何计划)可以解决问题,除非我找不到解决方案。
由于这是我加深理解的练习(JPQL查询已经有效),我正在寻找一个引用的参考,为什么这是不可能的,因为标准API的限制,如果这样做&#39;是这样的。
如果您想进一步调查,可以在https://gitlab.com/krichter/jpa-subquery-attribute-join找到SSCCE,这样可以节省您创建实体类的时间。