Java HQL:LIKE在null关系中

Java HQL:LIKE在null关系中,java,hibernate,jpa,null,hql,Java,Hibernate,Jpa,Null,Hql,我有一段独处的关系: public class Class1{ private String attr1; private String attr2; @OneToOne private Class2 object1; } public class Class2{ private String attr3; } 关系可以存储空对象(我的意思是Class1的实例在object1中可以有空对象)。我想在所有属性中进行完整搜索,因此我创建了此H

我有一段独处的关系:

public class Class1{

    private String attr1;
    private String attr2;

    @OneToOne
    private Class2 object1;

}

public class Class2{
    private String attr3;    
}
关系可以存储空对象(我的意思是Class1的实例在object1中可以有空对象)。我想在所有属性中进行完整搜索,因此我创建了此HQL查询:

SELECT p FROM Class1 p
WHERE 
(
upper(p.attr1) LIKE :filter OR
upper(p.attr2) LIKE :filter OR
upper(p.object1.attr3) LIKE :filter
)
我传递了一个大写的字符串param,前后都有“%”:

query.setParameter("filter", "%"+filter.trim().toUpperCase()+"%");
它可以正常工作,但适用于object1=null的实体。它永远不会得到那些实体。事实上,如果我删除最后一个条件(upper(p.object1.attr3)比如:filter),它会工作,但我需要包含它

我认为我应该用这种关系做一个左连接,所以我试着把它写成:

SELECT p FROM Class1 p LEFT JOIN p.object1 AS p1
WHERE 
(
upper(p.attr1) LIKE :filter OR
upper(p.attr2) LIKE :filter OR
upper(p1.attr3) LIKE :filter
)
或者

SELECT p FROM Class1 p LEFT JOIN p.object1 AS p1
WHERE 
(
upper(p.attr1) LIKE :filter OR
upper(p.attr2) LIKE :filter OR
(p1 is not null AND upper(p1.attr3) LIKE :filter)
)
但是没有成功

有什么想法吗


谢谢。

您必须使用外部联接

例如:

SELECT p FROM Class1 p OUTER JOIN p.object1 AS p1
   WHERE ... ;

据我所知,您需要值
p1.attr3为空
,当它为
非空
时,它应该验证条件。所以,我只是在微调您的最后一个查询

SELECT p FROM Class1 p LEFT JOIN p.object1 AS p1
WHERE 
(
upper(p.attr1) LIKE :filter OR
upper(p.attr2) LIKE :filter OR
(p1.attr3 is null OR upper(p1.attr3) LIKE :filter)
)

这是可行的,但效率很低。每当使用UNION时,数据库都必须对结果集进行完整排序(这就是为什么建议避免使用UNION或更喜欢UNION ALL,但在这里UNION ALL是不正确的)。外部联接是处理这种情况的有效方法。请。请看我的回答。我发现了问题所在。我有两个查询,一个用于计数,另一个用于选择,我只是在选择中更改左连接。所以,没有必要建立工会,没有工会就行。但是谢谢,我发现问题了。并不是说我需要一个外部连接。我有两个查询,一个用于计数,另一个用于选择,我只是在选择中更改左连接。但是谢谢你的建议。正如你看到的我留下的评论,问题是另一个问题。因此,您的答案是可以的(尽管甚至不需要检查p1是否为空)
SELECT p FROM Class1 p LEFT JOIN p.object1 AS p1
WHERE 
(
upper(p.attr1) LIKE :filter OR
upper(p.attr2) LIKE :filter OR
(p1.attr3 is null OR upper(p1.attr3) LIKE :filter)
)