HQL在OneToOne关系中检查NULL

时间:2018-10-16 16:24:05

标签: hibernate hql one-to-one

这是我的两个实体:

@Entity
@Table(name = "aog_reference")
public class AogReference
{
    @OneToOne(fetch = FetchType.LAZY, mappedBy="aogReference", cascade=CascadeType.ALL, optional=true)
    private Pack pack;

}

@Entity
@Table(name = "pack")
public class Pack
{

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="aog_reference")   
    private AogReference aogReference;

}

我可以使用Hibernate读写这两个实体,并且正确填充了AogReference的 pack 属性。

但是,我正在尝试运行一个HQL查询,该查询包含没有引用它们的包的AogReference实体。

已经阅读了很多有关此方面的内容,我希望它能起作用:

SELECT e FROM AogReference AS e left join e.pack  WHERE  (e.pack IS NULL) 

但是,即使我知道有些AogReference实体没有来自Pack实体的任何引用,我还是返回了0行。

我看了上面的hql生成的SQL,它看起来像这样:

   select
        aogreferen0_.id as id1_0_,
        aogreferen0_.active as active2_0_,
        aogreferen0_.created as created3_0_,
        aogreferen0_.modified as modified4_0_,
        aogreferen0_.version as version5_0_,
        aogreferen0_.aog_delivery_number as aog_deli6_0_,
        aogreferen0_.aog_destination as aog_dest7_0_,
        aogreferen0_.aog_notes as aog_note8_0_,
        aogreferen0_.foc_notification_time as foc_noti9_0_,
        aogreferen0_.is_collection_today as is_coll10_0_,
        aogreferen0_.is_used as is_used11_0_,
        aogreferen0_.work_stream as work_st12_0_ 
    from
        aog_reference aogreferen0_ 
    left outer join
        pack pack1_ 
            on aogreferen0_.id=pack1_.aog_reference 
    where
        aogreferen0_.id is null

或简化:

 select * 
 from 
   aog_reference a 
 left outer join 
    pack p on a.id = p.aog_reference 
 where a.id is null

现在注意怪物错误:

where a.id is null

Hibernate完全错了。生成的sql应该是这样的:

 select
        aogreferen0_.id as id1_0_,
        aogreferen0_.active as active2_0_,
        aogreferen0_.created as created3_0_,
        aogreferen0_.modified as modified4_0_,
        aogreferen0_.version as version5_0_,
        aogreferen0_.aog_delivery_number as aog_deli6_0_,
        aogreferen0_.aog_destination as aog_dest7_0_,
        aogreferen0_.aog_notes as aog_note8_0_,
        aogreferen0_.foc_notification_time as foc_noti9_0_,
        aogreferen0_.is_collection_today as is_coll10_0_,
        aogreferen0_.is_used as is_used11_0_,
        aogreferen0_.work_stream as work_st12_0_ 
    from
        aog_reference aogreferen0_ 
    left outer join
        pack pack1_ 
            on aogreferen0_.id=pack1_.aog_reference 
    where
        pack1_.id is null

请注意,现在最后一行:

 where pack1_.id is null

当它应该检查Pack的ID时,Hibernate生成的sql正在检查AogReference的ID。

当我在数据库中触发正确的sql时,它就会工作。

在我看来,这就像是Hibernate中的一个大型bug。它只是没有生成正确的sql。

感谢收到任何评论(明智的评论)。

谢谢

爱德。

更新:看来这是hibernate bug,自2010年以来一直存在。

1 个答案:

答案 0 :(得分:0)

正如您已经提到的,这似乎是一个已知的 hibernate bug

对于任何偶然发现这个问题的人。一种解决方法是使用“Exists”

SELECT e FROM AogReference e WHERE NOT EXISTS (SELECT p FROM Pack p WHERE p.aogReference = e)