Hibernate HQL与IS NULL的奇怪行为

时间:2010-08-03 21:11:33

标签: java hibernate hql

我遇到HQL查询问题。我希望将所有具有管理性别的PID设置为“M”或没有管理性(在Java中将值设置为null)。

PID.class

@Entity
@Table(name = "PatientIdentification")
public class PID {    

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "administrativeSex", referencedColumnName = "is_id")
    private IS administrativeSex;
    ...
}

IS.class

@Entity
@Table(name = "CodedValueForUserDefinedTables")
public class IS {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "is_id")
    private Integer id;

    private String value;
    ...
}

HQL查询

from PID where administrativeSex is null or administrativeSex.value = 'M'

生成的SQL

select
  pid0_.pid_id as pid1_84_,
  pid0_.administrativeSex as adminis11_84_,
  pid0_.birthOrder as birthOrder84_,
  pid0_.birthPlace as birthPlace84_,
  pid0_.citizenship as citizen12_84_,
  pid0_.countyCode as countyCode84_,
  pid0_.dateTimeOfBirth as dateTim19_84_,
  pid0_.driverLicenseNumber as driverL22_84_,
  pid0_.maritalStatus as maritalS8_84_,
  pid0_.multipleBirthIndicator as multiple4_84_,
  pid0_.nationality as nationa17_84_,
  pid0_.owner_id as owner9_84_,
  pid0_.patientAccountNumber as patientA6_84_,
  pid0_.patientDeathDateAndTime as patient16_84_,
  pid0_.patientDeathIndicator as patient18_84_,
  pid0_.patientId as patientId84_,
  pid0_.primaryLanguage as primaryL7_84_,
  pid0_.race as race84_,
  pid0_.religion as religion84_,
  pid0_.setId as setId84_,
  pid0_.ssnNumber as ssnNumber84_,
  pid0_.veteransMilitaryStatus as veterans2_84_
 from
  PatientIdentification pid0_,
  CodedValueForUserDefinedTables is1_
 where
  pid0_.administrativeSex=is1_.is_id
  and (
   pid0_.administrativeSex is null
   or is1_.value='M'
  )

查询仅返回管理性别设置为“M”的PID。它缺少一个没有行政性的人。如果查看SQL查询,这是正常的。如何更正我的HQL查询?

3 个答案:

答案 0 :(得分:7)

hibernate参考手册writes

  

HQL支持两种形式的关联   加入:隐式和显式。

     

前面显示的查询   部分都使用显式表格,   也就是说,join关键字的位置   在from子句中明确使用。   这是推荐的表格。

     

隐式表单不使用   加入关键字。相反,   使用“解除引用”关联   点符号。隐式连接可以   出现在任何HQL子句中。   隐式连接结果在内部连接中   生成的SQL语句。

由于内部联接过滤掉了连接条件不匹配的行,因此您缺少未知性别的人。您需要一个左外连接,您必须请求explicity

from PID pid
left outer join pid.administrativeSex as sex 
where pid.administrativeSex is null or sex.value = 'M'

答案 1 :(得分:1)

看起来你正在做一个内连接。

from
 PatientIdentification pid0_,
 CodedValueForUserDefinedTables is1_
where
 pid0_.administrativeSex=is1_.is_id
除非在CodedValueForUserDefinedTables中有一个条目,其中is_id也为null,否则

不会返回administrativeSex为null的任何值。

我发现OneToOne映射很难处理。您是否考虑过使用@SecondaryTable注释尝试将字符串值映射为顶级类中的字段?

答案 2 :(得分:1)

您是否考虑过直接使用外部联接?

from PID p left join p.administrativeSex with value = 'M'

希望有所帮助。