我正在努力应对JPA Criteria API子查询关联。从复杂的查询中,我用这个简单的案例复制了我的问题:
@Entity
public class Person {
@Id
Long id;
String name;
@ManyToMany
Set<Person> relatives;
}
CriteriaQuery<Long> criteriaQuery = criteriaBuilder.createQuery(Long.class);
Root<Person> from = criteriaQuery.from(Person.class);
Subquery<Long> subquery = criteriaQuery.subquery(Long.class);
SetJoin<Person, Person> correlate = subquery.correlate(from.joinSet("relatives"));
Subquery<Long> where = subquery.select(criteriaBuilder.count(correlate)).where(criteriaBuilder.equal(correlate.get("name"), "Giovanni"));
criteriaQuery = criteriaQuery.select(criteriaBuilder.count(from)).where(criteriaBuilder.greaterThan(where, 0L));
entityManager.createQuery(criteriaQuery).getSingleResult();
无法生成带有空from ...
子句的子查询:
select count(generatedAlias0)
from Person as generatedAlias0
inner join generatedAlias0.relatives as generatedAlias1
where (
select count(generatedAlias1)
from
where generatedAlias1.name=:param0
) > 0L
我认为correlate
会设置正确的from
。我错过了什么?
答案 0 :(得分:0)
我解决了这个问题:问题是用作correlate
参数的错误表达式。应该在原始 From
表达式上进行关联,而不是目标;即。
CriteriaQuery<Long> criteriaQuery = criteriaBuilder.createQuery(Long.class);
Root<Person> from = criteriaQuery.from(Person.class);
Subquery<Long> subquery = criteriaQuery.subquery(Long.class);
Root<Person> correlate = subquery.correlate(from);
// Instead of SetJoin<Person, Person> correlate = subquery.correlate(from.joinSet("relatives"));
Subquery<Long> where = subquery.select(criteriaBuilder.count(correlate)).where(
criteriaBuilder.equal(correlate.joinSet("relatives").get("name"), "Giovanni")
/* ^^^ instead of correlate.get("name") */
);
criteriaQuery = criteriaQuery.select(criteriaBuilder.count(from)).where(criteriaBuilder.greaterThan(where, 0L));
entityManager.createQuery(criteriaQuery).getSingleResult();