【问题标题】:Hibernate generates a "on ... and null=null" on left joinHibernate 在左连接上生成一个“on ... and null=null”
【发布时间】:2014-11-06 13:05:24
【问题描述】:

环境:

  • hibernate-entitymanager:4.3.6.Final
  • PostgreSQL 9.3.5

我执行当前这个 JPQL 查询

select distinct entity
from Incidence entity
  left join treat(entity.road as Road) as road
where entity.road is not null and lower(road.nomenclature) like :value 

查看日志文件,这会为 PostgreSQL 生成以下查询:

select
distinct 
....
....
from public.incidence incidence0_ 
left outer join public.road road1_ 
    on incidence0_.road=road1_.id and null=null 
where (incidence0_.road is not null)  and (lower(road1_.nomenclature) like ? )

使用%cv% 作为参数,这个查询应该返回 175 行,但我没有得到。

如果我在 PostgreSQL 上运行评论 and null=null 的查询,我会得到预期的结果:

select
distinct 
....
....
from public.incidence incidence0_ 
left outer join public.road road1_ 
    on incidence0_.road=road1_.id /* and null=null */
where (incidence0_.road is not null)  and (lower(road1_.nomenclature) like '%cv%' )

那么...为什么 hibernate 会在左连接中添加“null=null”条件?

我已经用 Oracle 进行了尝试,得到了完全相同的结果。

【问题讨论】:

    标签: hibernate postgresql jpa jpql


    【解决方案1】:

    经过多次证明,我发现问题在于treat表达式的使用。

    来自 JPA 2.1 规范:4.4.9 向下转换

    ...

    如果目标类型不是第一个参数的静态类型的子类型(正确或错误),则查询无效。

    在我的模型中,Road 是一个没有超类且没有子类型的实体类,所以,据我了解,我的 JPQL 应该抛出异常或者(因为是同类型) 忽略 treat 表达式

    我创建了一个关于它的Jira request

    【讨论】:

      【解决方案2】:

      不要使用entity.road is not null,而是尝试直接使用您的别名road

      select distinct entity
      from Incidence entity
      left join treat(entity.road as Road) as road
      where road is not null and      lower(road.nomenclature) like :value 
      

      因为当您使用 entity.road Hibernate 尝试添加隐式连接时,在您的情况下,它可能会在您的左连接和它自己的隐式连接之间混淆。

      如果您只希望Incidence 具有具有特定Road 值的Road,为什么不直接使用join 而不是left join

      【讨论】:

      • 经过多次证明发现问题出在treat表达式的使用上。我创建了一个关于它的Jira request。还是谢谢你。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 2013-02-25
      • 2013-05-17
      • 2014-08-29
      • 1970-01-01
      相关资源
      最近更新 更多