【问题标题】:Missing "from" in JPA correlated subqueryJPA 相关子查询中缺少“来自”
【发布时间】:2017-03-23 18:40:37
【问题描述】:

我正在努力处理 JPA 标准 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。我错过了什么?

【问题讨论】:

  • 如果这是最新版本,您应该提交错误报告。即使您使用的参数有问题,它仍然应该尝试更正它或抛出异常,但绝不会生成无效语法。
  • 它抛出一个“意外令牌”异常,所以我不认为这是一个错误。我在最新的 Hibernate 上,这在我看来是一个相当简单的查询,所以我宁愿认为我在相关性方面做错了……

标签: hibernate jpa correlated-subquery


【解决方案1】:

我会解决这个问题:问题是用作 correlate 参数的错误表达式。关联应该在 originating 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();

【讨论】:

    猜你喜欢
    • 2012-07-11
    • 2016-09-30
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 2020-06-08
    相关资源
    最近更新 更多