2 Stimmen

JPA 2 Criteria API: Warum wird isNull in Verbindung mit equal ignoriert?

Ich habe die folgende Entitätsklasse (ID geerbt von PersistentObjectSupport-Klasse):

@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. */
}

Wenn ich die folgende Abfrage mit der Criteria-API durchführe:

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();

Im Protokoll wird das folgende SQL ausgegeben:

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

Wenn ich jedoch die where()-Zeile im vorherigen Code in diese Zeile ändere:

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

Ich erhalte das folgende SQL:

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

Das heißt, das isNull-Kriterium wird völlig ignoriert. Es ist so, als ob es gar nicht vorhanden wäre (wenn ich der where()-Methode nur das Gleichheitskriterium gebe, bekomme ich die gleiche SQL ausgegeben).

Warum ist das so? Ist es ein Fehler oder übersehe ich etwas?

0 Stimmen

Übrigens habe ich einen Workaround - mit JPQL: em.createQuery("select d from AmbulanceDeactivation d where d.endDate is null and d.ambulance.id = " + ambulance.getId()).getSingleResult();. Ich möchte nur wissen, warum die Criteria API nicht funktioniert.

2voto

Pascal Thivent Punkte 548176

Ich habe Ihren Code und Ihre Kriterienabfrage mit EclipseLink getestet (Sie verwenden EclipseLink, richtig?) und das Verhalten reproduziert: die isNull Teil wird einfach ignoriert.

Mit Hibernate Entity Manager 3.5.1 wird jedoch die folgende Abfrage generiert:

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=?

Das ist das erwartete Ergebnis. Ich denke also, dass wir davon ausgehen können, dass dies ein Fehler Ihres JPA 2.0-Anbieters ist.

1voto

Miklos Krivan Punkte 1664

Ich hatte das gleiche seltsame Verhalten mit Glassfish 3.0.1, das EclipseLink 2.0 eingebettet hat.

Ich habe versucht, die eingebetteten Eclipselink-Bibliotheken mit der in Glassfish 3.1.2 enthaltenen Eclipselink 2.3-Bibliothek vorsichtig zu ändern. Das hat das Problem gelöst. Es ist also absolut sicher, dass die isNull-Prüfung in der gleichen Bedingung ein eclipselink-Bug ist, der criteriaBuilder verwendet.

Ich werde demnächst unsere GlassFish-Umgebung aktualisieren, um das Problem zu beheben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X