Обработка NULL с подвыбором в Hibernate Criteria API - PullRequest
2 голосов
/ 07 апреля 2010

Я создаю критерий гибернации, используя подвыбор следующим образом:

DetachedCriteria subselect =
    DetachedCriteria.forClass(NhmCode.class, "sub"); // the subselect selecting the maximum 'validFrom'
subselect.add(Restrictions.le("validFrom", new Date())); // it should be in the past (null needs handling here)
subselect.add(Property.forName("sub.lifeCycle").eqProperty("this.id")); // join to owning entity
subselect.setProjection(Projections.max("validFrom"));  // we are only interested in the maximum validFrom

Conjunction resultCriterion = Restrictions.conjunction();
resultCriterion.add(Restrictions.ilike(property, value)); // I have other Restrictions as well
resultCriterion.add(Property.forName("validFrom").eq(subselect)); // this fails when validFrom and the subselect return NULL

return resultCriterion;

Пока все работает нормально, но ограничение в последней строке перед оператором возврата ложно, когда validFrom и подвыбор приводят кНОЛЬ.

Мне нужна версия, которая обрабатывает этот случай как истину.Возможно, применяя NVL или коалесценцию или подобное.

Как мне это сделать?

Обновление: ----------------------------

Идея Петера с sqlRestriction приводит к выражению where, например:

        ...
        and (
            nhmcode1_.valid_from = (
                select
                    max(sub_.valid_from) as y0_ 
                from
                    nhm_code sub_ 
                where
                    sub_.valid_from<=? 
                    and sub_.lc_id=this_.id
            ) 
            or (
                nhmcode1_.valid_from is null 
                and sub.validFrom is null
            )
        )
        ...

, что в свою очередь приводит к:

ORA-00904: "SUB _". "VALIDFROM":ungültiger Bezeichner

сообщение об ошибке, означающее «неверный идентификатор»

Ответы [ 2 ]

5 голосов
/ 07 апреля 2010

Вы можете попробовать что-то вроде этого вместо проблемной строки:

resultCriterion.add(
  Restrictions.or(
    Restrictions.and(
      Restrictions.isNull("validFrom"),
      Restrictions.sqlRestriction("sub.validFrom is null")
    ),
    Property.forName("validFrom").eq(subselect)
  )
);

Это может не сработать сразу, но, надеюсь, поможет.

0 голосов
/ 10 июня 2010

Похоже, это еще одно ограничение API Criteria.

Я обнаружил, что на самом деле не так сложно создать свой собственный Критерий (или набор Критериев) для такого рода вещей.

Самая большая проблема в том, что вам придется обходиться без документации.Возьмите некоторые реализации, которые похожи на то, что вы хотите сделать.Настройте его, посмотрите, какой sql он генерирует, промойте и повторите.

Не весело, но это работает.

Извините, у меня нет реализации для проблемы в вопросе.

...