Hibernate HQL странное поведение с IS NULL - PullRequest
2 голосов
/ 04 августа 2010

У меня проблема с HQL-запросом. Я хочу получить все PID с административным полом, установленным в 'M', или без административного пола (в Java это значение равно нулю).

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-запрос?

Ответы [ 3 ]

7 голосов
/ 04 августа 2010

Справочное руководство по Hibernate пишет :

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

Все запросы, показанные в предыдущем разделеиспользуйте явную форму, то есть где ключевое слово join явно используется в предложении from.Это рекомендуемая форма.

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

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

from PID pid
left outer join pid.administrativeSex as sex 
where pid.administrativeSex is null or sex.value = 'M'
1 голос
/ 04 августа 2010

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

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

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

1 голос
/ 04 августа 2010

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

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

не будет возвращать никаких значений, если administratorSex имеет значение null, если у вас нет записи в CodedValueForUserDefinedTables, где is_id также равно NULL.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...