Hibernate/JPA:如何强制隐式连接使用左外部连接

Hibernate/JPA:如何强制隐式连接使用左外部连接,hibernate,jpa,hql,outer-join,jql,Hibernate,Jpa,Hql,Outer Join,Jql,有一个类报价,它与类文章有可选关系。因此,某些offers-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' 如果我将声明更改为

有一个类
报价
,它与类
文章
可选关系。因此,某些offers-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.numer
)强制内部联接

是否有可能强制左外部联接到隐式联接(注释驱动或其他)?如果有机会,我可以用这样一个简短的形式:

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

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

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

//...

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

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

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

  • 使用显式连接信息构建查询
  • 使用条件,这可能最适合动态查询构建

首先,如果您尝试使用o.article.numer而不是a.numer,我相信它会添加一个带有内部联接的额外WHERE子句。没有办法明确地说是左连接。但无论如何,您都是在查询中自己指定的,因此只需使用别名a.number='23456'中的联接实体即可

因为您知道该字段是可空的,所以不能像在SQL中对可空字段使用=一样使用=。为此,请使用COALESCE将空值转换为空字符串:

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'

我有一个类似的问题:我有一个
generafacility
-表,其中包含一列
SpecificType
。并非所有设施都有此类型,由于SpecificType在GeneralFacility表中是内部联接的,因此没有特定类型的条目属于该表

我把问题解决了

    @Fetch(FetchMode.SELECT)

在模型中的
@ManyToOne
-行旁边。该类型现在在一个单独的查询中获取,如果没有返回任何内容,则不会丢弃GeneralFacility查询的结果。

OP没有说有任何动态内容。“0212”和“123456”的用法表明查询在运行时发生了更改。我为“使用正确的SQL连接”找到的解决方案之一是使用CriteriaAPI。标准API通常使用起来更复杂,不如HQL强大。如果只有值更改,只需将参数放入查询中。这不是真正的“动态”,而是参数化的。我想这只适用于使用
session.get
获取实体的情况。当您在HQL查询中需要该属性时,据我所知,它不会产生影响。我不知道这应该如何解决问题。AFAIK Fetchmode仅指定如何获取数据以初始化内存中的对象,而不指定如何在查询中进行连接。