2009-12-09 6 views
7

Ich stieß auf einige ähnliche Fragen auf StackOverflow, versuchte die Lösungen, fand aber keine Antwort.EclipseLink JPA `@ PreUpdate` Aufruf nicht persistent

Ich verwende eine ziemlich häufige JPA-Strategie, um die letzten modifizierten Zeiten für einige Entitäten festzulegen. Richten Sie die Spalten und Felder ein, markieren Sie eine Methode mit @PreUpdate und lassen Sie sie gleich der aktuellen Zeit setzen.

Das Problem ist, dass ich im Debugger sehen kann, dass die Methode aufgerufen wird und dass das Feld aktualisiert wird, jedoch in meinen DB-Protokollen sehe ich nur einen SQL-Aufruf UPDATE das geänderte Feld, das kein UPDATE enthält für das Zeitstempelfeld.

verkompliziert die Dinge weiter @PrePersist funktioniert perfekt, nur @PreUpdate exibits dieses Verhalten.

Die nächste Erklärung, die ich bisher gefunden habe, ist LINK.

ähnliche Fragen an: # 1725699 und # 1745890

Ich bin mit Eclipse v2 und v1 JPA für die Kompatibilität mit Glassfish v2.

Ich habe versucht, beide Annotationen direkt auf Methoden in der Entity-Klasse sowie eine EntityListener an die Entity-Klasse mit der @EntityListener Annotation angefügt.

Ich vermute, das ist ein Fehler in EclipseLink, aber ich kann es nicht beweisen.

Bug oder nicht Ich würde sehr gerne diese einfache Operation zu arbeiten. Ist etwas falsch mit dieser Implementierung? Ist das ein bekanntes Problem in EclipseLink? Ist das ein bekanntes Problem in JPA? Gibt es einen Weg dahin?

Kurz in die Datenbank gehen und Trigger verwenden, gibt es einen alternativen Pfad, um meinen Java-Code den updated_on-Zeitstempel setzen zu lassen?

Danke für den Hinweis!

Codefragmente folgen.

Entity Felder:

@Column(name = "updated_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date updatedOn; 
@Column(name = "created_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date createdOn; 

Kommentierte Aktualisierungsmethoden:

@PreUpdate 
public void setUpdatedOn(Timestamped object) { 
    object.setUpdatedOn(new Date()); 
} 

@PrePersist 
public void setCreatedOn(Timestamped object) { 
    if (object.getCreatedOn()==null) { 
     object.setCreatedOn(new Date()); 
    } 
} 

Antwort

4

Der Link, den Sie bieten beschreibt genau Ihre Situation: für die schmutzige Prüfung, aktualisiert Felder erkannt werden, bevor die @PreUpdate Methode aufgerufen wird und Änderungen in der @ PreUpdate-Methode werden nicht mehr erkannt. Dies wird wahrscheinlich aus Performance-Gründen getan, da Dirty-Checks bei großen Objektgraphen sehr teuer sein können. Momentan haben Sie die Wahl, einen Provider-spezifischen Mechanismus (DescriptorEvent) zu verwenden oder zu Hibernate zu wechseln.

+0

Felix definieren - für die Klärung Danke. Ich dachte, das ist was ich sah. Ich sehe, wie die DescriptorEvent-Behandlung zu implementieren, fast so einfach wie ein paar Methoden notieren. Ich muss nur die richtige XML-Datei finden, um den Handler hinzuzufügen. Danke nochmal! – Freiheit

+0

Hallo Freiheit, ich stehe jetzt vor dem gleichen Problem, würden Sie Ihren DescriptorEvent-Code als Beispiel verwenden? :) danke – sunnycmf

+0

@Freiheit würde gerne die Lösung auch sehen. Danke im Voraus. –

3

Mybe ein bisschen spät, aber von Informationen auf Vollständigkeit dies ist kein Fehler, sondern ein dokumentiertes Verhalten:

Datum oder Kalendertypen werden angenommen NICHT standardmäßig wandelbar zu sein, wenn es gewünscht ist, Um die festgelegten Methoden für das Datum oder den Kalender aufzurufen, muss die Zuordnung auf @Mutable festgelegt werden.

Für Datums- und Kalendertypen kann die globale Persistenzeigenschaft "eclipselink.temporal.mutable" auch auf "true" gesetzt werden.

so, entweder mit Anmerkungen versehen

@Mutable 
@Column(name = "updated_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date updatedOn; 

oder

<property name="eclipselink.temporal.mutable" value="true" /> 

in persistence.xml

+0

Vielen Dank Michele, Es ist Arbeit mit mir wie ein Charme. –

+0

Sie sind willkommen :) –

+0

Ich habe diese Annotation hinzugefügt, aber es funktioniert immer noch nicht ([siehe meine Frage] (https://stackoverflow.com/questions/47081932/prepersist-not-working-with-mappedsuperclass-in-hibernate -Frühling-Umgebung)). Irgendeine Idee warum? – displayname