Hibernate / JPA:如何强制隐式连接使用LEFT OUTER JOINS

时间:2012-01-25 15:34:01

标签: hibernate jpa hql outer-join jql

有一个班级Offer与班级Article可选关系。因此,某些商品属性包含null值。

如果我使用以下声明,一切正常。我得到了所有的报价,甚至那些没有文章的报价。

SELECT o FROM Offer o 
         LEFT OUTER JOIN o.article a 
         LEFT OUTER JOIN o.vendor v 
         WHERE v.number = '0212' OR a.nummer = '123456'

如果我将声明更改为:

SELECT o FROM Offer o 
         LEFT OUTER JOIN o.article a 
         LEFT OUTER JOIN o.vendor v 
         WHERE v.number = '0212' OR o.article.nummer = '123456'

我只获得了与NULL不同的文章。这是因为隐式连接的表示法(o.article.nummer)强制内连接。

是否有可能强制左外连接到隐式连接(注释驱动或其他)?如果有可能我可以使用这样的简短形式:

SELECT o FROM Offer o 
         WHERE v.number = '0212' OR o.article.nummer = '123456'

4 个答案:

答案 0 :(得分:4)

您可以尝试将@Fetch(FetchMode.JOIN)放在Article属性上。但是,这是一个Hibernate注释。

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

//...

@ManyToOne
@Fetch(FetchMode.JOIN)
Article article;

答案 1 :(得分:1)

据我所知,Hibernate 提供了一种方法来更改HQL查询的默认隐式关联连接形式。

我能找到的最佳解决方案是:

  • 使用显式连接信息构建查询;
  • 使用标准,这可能是动态查询构建的最佳选择。

答案 2 :(得分:1)

我有一个类似的问题:我有某种GeneralFacility - 表,其中包含一列SpecificType。并非所有工具都具有此类型,并且由于特定类型是在没有特定类型的GeneralFacility-Table条目的内部连接,因此属于该表。

我把

解决了问题
    @Fetch(FetchMode.SELECT)

在模型中的@ManyToOne - 行旁边。现在,类型将在单独的查询中获取,如果确实没有返回,则不会丢弃GeneralFacility查询的结果。

答案 3 :(得分:0)

首先,如果你尝试使用o.article.nummer而不是a.nummer,我相信它会在内部连接中加入一个额外的WHERE子句。 Thre无法明确表示左连接。但是你无论如何都要在查询中自己指定它,所以只需使用别名中的连接实体a.number =' 23456'。

由于您知道该字段可以为空,因此您无法使用=,因为您无法在可空字段的SQL中使用=。而是使用COALESCE将NULL值转换为空字符串:

SELECT o FROM Offer o 
    LEFT OUTER JOIN o.article a
    LEFT OUTER JOIN o.vendor v 
        WHERE v.number = '0212'
        OR COALESCE(a.nummer,'') = '123456'