JPQL 中的 HQL 'with' 子句

Posted

技术标签:

【中文标题】JPQL 中的 HQL \'with\' 子句【英文标题】:HQL 'with' clause in JPQLJPQL 中的 HQL 'with' 子句 【发布时间】:2012-09-05 19:40:02 【问题描述】:

来自 Hibernate 3.6 文档:

您可以使用 HQL with 关键字提供额外的连接条件。

from Cat as cat
left join cat.kittens as kitten
    with kitten.bodyWeight > 10.0

with 子句允许对 JOIN 条件(ON 子句)添加限制。 JPQL里有这样的东西吗?

当我运行以下 JPQL 时:

select c from ContainerDef c left join fetch c.displayState ds where c.id = 1 and ds.user.id = 2

生成如下SQL:

select
        ...
    from
        CONTAINER_DEF containerd0_ 
    left outer join
        USER_CONTAINERDEF displaysta1_ 
            on containerd0_.CONTAINERDEF_ID=displaysta1_.CONTAINERDEF_ID 
    where
        containerd0_.CONTAINERDEF_ID=? 
        and displaysta1_.AUTHUSER_ID=?

真正应该生成的是:

select
        ...
    from
        CONTAINER_DEF containerd0_ 
    left outer join
        USER_CONTAINERDEF displaysta1_ 
            on containerd0_.CONTAINERDEF_ID=displaysta1_.CONTAINERDEF_ID 
            and displaysta1_.AUTHUSER_ID=?
    where
        containerd0_.CONTAINERDEF_ID=? 

我确定我错过了 HQL 的 with 的正确 JPQL 子句。

【问题讨论】:

来自 Hibernate 文档:HQL also defines a WITH clause to qualify the join conditions. Again, this is specific to HQL; JPQL does not define this feature.docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/… 请注意,在 Hibernate 中,您也可以在 JPQL 中使用 with @axtavt 我试过了,它抛出了 IllegalArgumentException。 【参考方案1】:

但您可以使用 Criteria API 来做到这一点

    Criteria crit = session.createCriteria(Cat.class);
    crit.createAlias("kittens", "kitten", 
        Criteria.LEFT_JOIN, Restrictions.gt("weight", 10.0);

    List<Cat> catsWithFatKittens = crit.list(); 

这是 Criteria.createAlias() 几乎没有记录的签名,其中 Restriction 对象作为第四个参数。它运行良好,值得学习 Criteria API 来获得该功能。

【讨论】:

【参考方案2】:

JPA 2.1 添加了对ON join 条件的支持。

这也是比 HQL 'with' 子句更好的名称选择。

【讨论】:

【参考方案3】:

不,JPQL 中没有这样的功能。 JPA 2.1 topic list中提到了对特定条件加入的支持:

--支持ON条件的外连接;

所以也许 JPQL 将来会有它。

【讨论】:

以上是关于JPQL 中的 HQL 'with' 子句的主要内容,如果未能解决你的问题,请参考以下文章

正确的表达式不是 JPQL/HQL 查询中的有效表达式

JPQL 中的 LIMIT 子句替代方案是啥?

HQL 错误:with 子句引用了两个不同的 from 子句元素

类似子句 JPQL 中的参数

使用 JPQL/HQL 在 JPA 中订购连接获取的集合

将列表传递给 HQL 或 SQL 中的 IN 子句?