Критерии API JPA 2: Почему isnull игнорируется, когда в сочетании с равным?
-
26-09-2019 - |
Вопрос
У меня есть следующий класс сущности (ID унаследован от класса 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:
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)
Однако, если я изменю линию где () в предыдущем коде к этому:
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 полностью игнорируется. Как будто это даже не было (если я предоставлю только одинаковый критерий к методу, который я получаю тот же SQL напечатанный).
Почему это? Это ошибка или я что-то упускаю?
Решение
Я проверял ваш запрос кода и критерии с 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.
Другие советы
У меня было такое же странное поведение, используя Glassfish 3.0.1, который встроен ECLIPSELINK 2.0.
Я пытался изменить встроенные библиотеки ECLIPSELINK с Glassfish 3.1.2, содержали библиотеку EclipseLink 2.3. Это решило проблему. Таким образом, абсолютно уверены, что проверка isnull в равном состоянии - это ошибка EclipseLink, использующая критерии.
Я скоро обновись в ближайшее время нашу среду Glassfish, чтобы устранить проблему.