4 Stimmen

JPA EntityManager-Zwischenspeicherung

Ich habe eine Entität wie folgt definiert:

public class Version {
    @Id
    private Long id;
    private String content;
    @Transient
    private Model model;

    //...
}

Soweit ich das beurteilen kann, wird ein find Operation auf dem Entity Manager durchgeführt wird, macht er eine SELECT auf der zugrundeliegenden Datenbank nur einmal, und dann wird die Entität im Entity Manager zwischengespeichert. Ich sehe jedoch, dass, wenn ich eine Model zum model Eigenschaft, wird diese Änderung nicht in die zwischengespeicherte Entität übernommen. Wenn z. B. in einem Aufruf eine find Vorgang abgeschlossen ist und Model zugewiesen ist, wenn ich find wieder von einer anderen EJB, model Eigenschaft ist null wieder. Wird diese Änderung nicht auf die zwischengespeicherte Entität übertragen? Vielleicht weil es sich um @Transient ?

10voto

JB Nizet Punkte 654813

Der Entity-Manager unterhält einen Cache der ersten Ebene, der nach Beendigung der Transaktion verworfen wird. Andernfalls würde der Cache veraltete Werte zurückgeben, da andere Transaktionen in derselben oder einer anderen Anwendung die zwischengespeicherten Entitäten ändern oder entfernen könnten.

Darüber hinaus haben konkurrierende Transaktionen jeweils ihren eigenen Session-Level-Cache und damit ihre eigene Instanz derselben Entität.

Wenn Sie in einer späteren Transaktion find die gleiche Entität, wird eine neue SQL-Abfrage gestellt, und es wird eine andere Instanz der Entität zurückgegeben.

Wenn etwas über Transaktionen hinweg für eine bestimmte Entität gespeichert werden muss, dann sollte es in der Datenbank persistent gemacht werden. Das ist der Sinn einer Datenbank.

3voto

thisismydesign Punkte 14173

Ich muss @JB Nizet nicht zustimmen. Der EntityManager von JPA und die Session von Hibernate bieten einen erweiterten Persistenzkontext. Es ist überhaupt nicht wahr, dass "der Cache der ersten Ebene weggeworfen wird, sobald die Transaktion beendet ist".

Der Persistenzkontext kann entweder transaktionsbezogen sein - der P Context 'lebt' für die Dauer der Transaktion, oder Extended - der Persistenzkontext erstreckt sich über mehrere Transaktionen.

https://web.archive.org/web/20131212234524/https://blogs.oracle.com/carolmcdonald/entry/jpa_caching

Die Lösung ist jedoch richtig, Sie müssen Änderungen am Objekt beibehalten, wenn Sie möchten, dass es im Cache geändert wird.

2voto

James Punkte 18499

Wenn Sie EclipseLink verwenden, kann das Zusammenführen in den gemeinsamen Cache von Transienten auf zwei Arten konfiguriert werden.

Wenn eine @CloneCopyPolicy verwendet wird, wird das Objekt aus dem Persistenzkontext in den gemeinsamen Cache geklont, wobei die transienten Felder erhalten bleiben.

Wenn eine @InstantiationCopyPolicy verwendet wird, wird eine neue Instanz für den gemeinsamen Cache erstellt, und Transienten werden nicht beibehalten.

Wenn Sie Weaving und Feldzugriff verwenden, ist der Standardwert @CloneCopyPolicy, ansonsten @InstantiationCopyPolicy. Sie können dies auch konfigurieren mit

Mit einem DescriptorEventListener und den postMerge/PostClone-Ereignissen können Sie auch steuern, was in den gemeinsamen Cache aufgenommen wird.

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