2010-08-03 3 views
2

У меня проблема с запросом HQL. Я хочу получить все PID, у которого есть административный секс, установленный на «M» или без административного секса (в Java значение равно null).Hibernate HQL странное поведение с IS 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' 
) 

Запрос возвращает только идентификатор PID, для которого административный пол установлен в 'M'. Это не тот, у кого нет административного секса. Это нормально, если вы посмотрите на SQL-запрос. Как я могу исправить свой HQL-запрос?

ответ

7

зимуют Справочное руководство writes:

HQL поддерживает две формы объединения присоединения: явные и неявные.

Запросы, приведенные в предыдущем разделе все используют в явном виде, , то есть, где присоединиться ключевое слово явно используется в ЕКОМ. Рекомендуемая форма.

В неявной форме не используется ключевое слово join . Вместо этого ассоциации «разыменовываются» с использованием меток . неявные объединения могут появляться в любом из предложений HQL. неявный результат объединения во внутренних объединениях в в результате SQL-инструкции.

Поскольку внутреннее соединение отфильтровывает те строки, в которых условие объединения не совпадает, вам не хватает людей неизвестного пола. Вы хотите, левое внешнее соединение, которое вы должны запросить explicity:

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

@meriton Я согласен –

+0

Это не работает для меня.Мне пришлось сменить LEFT OUTER JOIN на LEFT JOIN. Любые идеи почему? – chris

1

Похоже, вы делаете эквивалент внутреннего соединения.

from 
PatientIdentification pid0_, 
CodedValueForUserDefinedTables is1_ 
where 
pid0_.administrativeSex=is1_.is_id 

не собирается возвращать любые значения, где administrativeSex является нуль, если у вас есть запись в CodedValueForUserDefinedTables где is_id также нуль.

Я считаю, что отображение OneToOne будет сложным для работы. Считаете ли вы попыткой сопоставить строковое значение как поле в классе верхнего уровня, используя аннотацию @SecondaryTable?

+0

часть «если» неверна, так как NULL = NULL не является истинным в SQL. – meriton

1

Рассматривали ли вы с помощью внешнего соединения напрямую?

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

Надеюсь, что это поможет.

+0

Это работает для моей проблемы. благодаря – chris

Смежные вопросы