JPA 2 Criteria API: почему isNull игнорируется в сочетании с равным? - PullRequest
2 голосов
/ 10 июня 2010

У меня есть следующий класс сущностей (идентификатор, унаследованный от класса PersistentObjectSupport):

@Entity
public class AmbulanceDeactivation extends PersistentObjectSupport implements Serializable {
    private static final long serialVersionUID = 1L;

    @Temporal(TemporalType.DATE) @NotNull
    private Date beginDate;

    @Temporal(TemporalType.DATE)
    private Date endDate;

    @Size(max = 250)
    private String reason;

    @ManyToOne @NotNull
    private Ambulance ambulance;

    /* Get/set methods, etc. */
}

Если я выполняю следующий запрос с использованием API Criteria:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<AmbulanceDeactivation> cq = cb.createQuery(AmbulanceDeactivation.class);
Root<AmbulanceDeactivation> root = cq.from(AmbulanceDeactivation.class);
EntityType<AmbulanceDeactivation> model = root.getModel();
cq.where(cb.isNull(root.get(model.getSingularAttribute("endDate", Date.class))));
return em.createQuery(cq).getResultList();

, я получаю следующееSQL напечатан в журнале:

FINE: SELECT ID, REASON, ENDDATE, UUID, BEGINDATE, VERSION, AMBULANCE_ID FROM AMBULANCEDEACTIVATION WHERE (ENDDATE IS NULL)

Однако, если я изменю строку where () в предыдущем коде на эту:

cq.where(cb.isNull(root.get(model.getSingularAttribute("endDate", Date.class))),
    cb.equal(root.get(model.getSingularAttribute("ambulance", Ambulance.class)), ambulance));

, я получу следующий SQL:

FINE: SELECT ID, REASON, ENDDATE, UUID, BEGINDATE, VERSION, AMBULANCE_ID FROM AMBULANCEDEACTIVATION WHERE (AMBULANCE_ID = ?)

То есть критерий isNull полностью игнорируется.Это как если бы его там даже не было (если я предоставляю только равный критерий методу where (), я получаю тот же SQL-код).

Почему это так?Это ошибка или я что-то упустил?

Ответы [ 2 ]

2 голосов
/ 11 июня 2010

Я протестировал ваш запрос кода и критериев с помощью EclipseLink (вы используете EclipseLink, верно?) И воспроизвел поведение: часть isNull просто игнорируется.

Однако в Hibernate Entity Manager 3.5.1 генерируется следующий запрос:

select ambulanced0_.id as id7_, ambulanced0_.ambulance_id as ambulance5_7_, ambulanced0_.beginDate as beginDate7_, ambulanced0_.endDate as endDate7_, ambulanced0_.reason as reason7_ 
from AmbulanceDeactivation ambulanced0_ 
where (ambulanced0_.endDate is null) and ambulanced0_.ambulance_id=?

Какой ожидаемый результат. Поэтому я думаю, что мы можем предположить, что это ошибка вашего провайдера JPA 2.0.

1 голос
/ 08 февраля 2013

У меня было такое же странное поведение при использовании Glassfish 3.0.1 со встроенным EclipseLink 2.0.

Я попытался изменить встроенные библиотеки eclipselink с помощью библиотеки Glassfish 3.1.2, содержащей библиотеку Eclipselink 2.3. Это решило проблему. Поэтому абсолютно уверен, что проверка isNull в одинаковом состоянии является ошибкой eclipselink с использованием критерия Builder.

Я скоро обновлю нашу среду GlassFish, чтобы устранить проблему.

...