EntityManager.merge()
kann neue Objekte einfügen und vorhandene aktualisieren.
Warum sollte man verwenden wollen persist()
(was nur neue Objekte erstellen kann)?
EntityManager.merge()
kann neue Objekte einfügen und vorhandene aktualisieren.
Warum sollte man verwenden wollen persist()
(was nur neue Objekte erstellen kann)?
Antworten:
In beiden Fällen wird eine Entität zu einem PersistenceContext hinzugefügt. Der Unterschied besteht darin, was Sie anschließend mit der Entität tun.
Persist nimmt eine Entitätsinstanz, fügt sie dem Kontext hinzu und verwaltet diese Instanz (dh zukünftige Aktualisierungen der Entität werden nachverfolgt).
Zusammenführen gibt die verwaltete Instanz zurück, mit der der Status zusammengeführt wurde. Es gibt etwas zurück, was in PersistenceContext vorhanden ist, oder erstellt eine neue Instanz Ihrer Entität. In jedem Fall wird der Status von der angegebenen Entität kopiert und die verwaltete Kopie zurückgegeben. Die von Ihnen übergebene Instanz wird nicht verwaltet (alle von Ihnen vorgenommenen Änderungen sind nicht Teil der Transaktion - es sei denn, Sie rufen die Zusammenführung erneut auf). Sie können die zurückgegebene Instanz (verwaltete) verwenden.
Vielleicht hilft ein Codebeispiel.
MyEntity e = new MyEntity();
// scenario 1
// tran starts
em.persist(e);
e.setSomeField(someValue);
// tran ends, and the row for someField is updated in the database
// scenario 2
// tran starts
e = new MyEntity();
em.merge(e);
e.setSomeField(anotherValue);
// tran ends but the row for someField is not updated in the database
// (you made the changes *after* merging)
// scenario 3
// tran starts
e = new MyEntity();
MyEntity e2 = em.merge(e);
e2.setSomeField(anotherValue);
// tran ends and the row for someField is updated
// (the changes were made to e2, not e)
Szenario 1 und 3 sind ungefähr gleichwertig, aber es gibt Situationen, in denen Sie Szenario 2 verwenden möchten.
merge
die vollständige Kopie eines Objekts vor der Verwaltung einen Leistungseinbruch?
@GeneratedId
kann ich sie in Szenario 2 bekommen?
Das Fortbestehen und Zusammenführen dient zwei verschiedenen Zwecken (sie sind überhaupt keine Alternativen).
(bearbeitet, um Informationen zu Unterschieden zu erweitern)
fortdauern:
verschmelzen:
persist () Effizienz:
persist () Semantik:
Beispiel:
{
AnyEntity newEntity;
AnyEntity nonAttachedEntity;
AnyEntity attachedEntity;
// Create a new entity and persist it
newEntity = new AnyEntity();
em.persist(newEntity);
// Save 1 to the database at next flush
newEntity.setValue(1);
// Create a new entity with the same Id than the persisted one.
AnyEntity nonAttachedEntity = new AnyEntity();
nonAttachedEntity.setId(newEntity.getId());
// Save 2 to the database at next flush instead of 1!!!
nonAttachedEntity.setValue(2);
attachedEntity = em.merge(nonAttachedEntity);
// This condition returns true
// merge has found the already attached object (newEntity) and returns it.
if(attachedEntity==newEntity) {
System.out.print("They are the same object!");
}
// Set 3 to value
attachedEntity.setValue(3);
// Really, now both are the same object. Prints 3
System.out.println(newEntity.getValue());
// Modify the un attached object has no effect to the entity manager
// nor to the other objects
nonAttachedEntity.setValue(42);
}
Auf diese Weise existiert nur 1 angehängtes Objekt für ein Register im Entitätsmanager.
merge () für eine Entität mit einer ID ist ungefähr so:
AnyEntity myMerge(AnyEntity entityToSave) {
AnyEntity attached = em.find(AnyEntity.class, entityToSave.getId());
if(attached==null) {
attached = new AnyEntity();
em.persist(attached);
}
BeanUtils.copyProperties(attached, entityToSave);
return attached;
}
Wenn eine Verbindung zu MySQL merge () genauso effizient sein könnte wie persist (), wenn ein Aufruf von INSERT mit der Option ON DUPLICATE KEY UPDATE verwendet wird, ist JPA eine Programmierung auf sehr hoher Ebene, und Sie können nicht davon ausgehen, dass dies überall der Fall sein wird.
em.persist(x)
mit x = em.merge(x)
?
merge()
kann auch einEntityExistsException
RuntimeException
, aber es wird im Javadoc nicht erwähnt.
Wenn Sie den zugewiesenen Generator verwenden, kann die Verwendung von Merge anstelle von Persist eine redundante SQL-Anweisung verursachen und somit die Leistung beeinträchtigen.
Das Aufrufen der Zusammenführung für verwaltete Entitäten ist ebenfalls ein Fehler, da verwaltete Entitäten automatisch von Hibernate verwaltet werden und ihr Status beim Löschen des Persistenzkontexts durch den Dirty-Checking-Mechanismus mit dem Datenbankdatensatz synchronisiert wird .
Um zu verstehen, wie dies alles funktioniert, sollten Sie zunächst wissen, dass Hibernate die Entwickler-Denkweise von SQL-Anweisungen zu Entitätsstatusübergängen verschiebt .
Sobald eine Entität von Hibernate aktiv verwaltet wird, werden alle Änderungen automatisch an die Datenbank weitergegeben.
Der Ruhezustand überwacht derzeit angeschlossene Entitäten. Damit eine Entität verwaltet werden kann, muss sie sich im richtigen Entitätsstatus befinden.
Um die JPA-Statusübergänge besser zu verstehen, können Sie das folgende Diagramm visualisieren:
Oder wenn Sie die Hibernate-spezifische API verwenden:
Wie in den obigen Diagrammen dargestellt, kann sich eine Entität in einem der folgenden vier Zustände befinden:
Neu (vorübergehend)
Ein neu erstelltes Objekt, das noch nie einem Ruhezustand Session
(aka Persistence Context
) zugeordnet wurde und keiner Datenbanktabellenzeile zugeordnet ist, befindet sich im Status Neu (vorübergehend).
Um persistent zu werden, müssen wir entweder die EntityManager#persist
Methode explizit aufrufen oder den transitiven Persistenzmechanismus verwenden.
Dauerhaft (verwaltet)
Eine persistente Entität wurde einer Datenbanktabellenzeile zugeordnet und wird vom aktuell ausgeführten Persistenzkontext verwaltet. Jede an einer solchen Entität vorgenommene Änderung wird erkannt und an die Datenbank weitergegeben (während der Sitzungsspülzeit). Mit Hibernate müssen wir keine INSERT / UPDATE / DELETE-Anweisungen mehr ausführen. Der Ruhezustand verwendet einen Transaktions-Write-Behind- Arbeitsstil und Änderungen werden im allerletzten verantwortlichen Moment während der aktuellen Session
Spülzeit synchronisiert .
Freistehend
Sobald der aktuell ausgeführte Persistenzkontext geschlossen ist, werden alle zuvor verwalteten Entitäten getrennt. Aufeinanderfolgende Änderungen werden nicht mehr verfolgt und es findet keine automatische Datenbanksynchronisierung statt.
Um eine getrennte Entität einer aktiven Ruhezustandssitzung zuzuordnen, können Sie eine der folgenden Optionen auswählen:
Wiederanbringen
Der Ruhezustand (aber nicht JPA 2.1) unterstützt das erneute Anhängen über die Aktualisierungsmethode "Sitzung #". Eine Ruhezustandssitzung kann nur ein Entitätsobjekt für eine bestimmte Datenbankzeile zuordnen. Dies liegt daran, dass der Persistenzkontext als speicherinterner Cache (Cache der ersten Ebene) fungiert und einem bestimmten Schlüssel (Entitätstyp und Datenbankkennung) nur ein Wert (Entität) zugeordnet ist. Eine Entität kann nur dann erneut zugeordnet werden, wenn der aktuellen Ruhezustandssitzung noch kein anderes JVM-Objekt (das mit derselben Datenbankzeile übereinstimmt) bereits zugeordnet ist.
Zusammenführen
Durch die Zusammenführung wird der Status der getrennten Entität (Quelle) in eine Instanz einer verwalteten Entität (Ziel) kopiert. Wenn die zusammengeführte Entität in der aktuellen Sitzung keine Entsprechung hat, wird eine aus der Datenbank abgerufen. Die Instanz des getrennten Objekts bleibt auch nach dem Zusammenführungsvorgang weiterhin getrennt.
Entfernt
Obwohl JPA verlangt, dass nur verwaltete Entitäten entfernt werden dürfen, kann Hibernate auch getrennte Entitäten löschen (jedoch nur über einen Aufruf der Methode Session # delete). Eine entfernte Entität ist nur zum Löschen geplant und die eigentliche DELETE-Anweisung der Datenbank wird während der Sitzungsspülzeit ausgeführt.
Ich bemerkte, dass ich bei der Verwendung für jedes em.merge
eine SELECT
Anweisung erhielt INSERT
, auch wenn es kein Feld gab, das JPA für mich generierte - das Primärschlüsselfeld war eine UUID, die ich selbst festgelegt hatte. Ich wechselte zu em.persist(myEntityObject)
und bekam dann nur INSERT
Aussagen.
merge()
. Ich hatte eine PostgreSQL-Datenbank mit komplizierter Ansicht : Die Ansicht aggregierte Daten aus mehreren Tabellen (die Tabellen hatten identische Struktur, aber unterschiedliche Namen). Also versuchte JPA dies merge()
, aber tatsächlich wurde JPA zuerst erstellt SELECT
(Datenbank aufgrund von Ansichtseinstellungen konnte mehrere Datensätze mit demselben Primärschlüssel aus verschiedenen Tabellen zurückgeben!), Dann schlug JPA (Ruhezustand war eine Implementierung) fehl: Es gibt mehrere Datensätze mit demselben Schlüssel ( org.hibernate.HibernateException: More than one row with the given identifier was found
). In meinem Fall persist()
hat mir geholfen.
Die JPA-Spezifikation sagt Folgendes über persist()
.
Wenn X ein getrenntes Objekt ist,
EntityExistsException
kann das Objekt ausgelöst werden, wenn die Persist-Operation aufgerufen wird, oder dasEntityExistsException
oder ein anderes ObjektPersistenceException
kann zur Flush- oder Commit-Zeit ausgelöst werden.
Die Verwendung persist()
wäre daher geeignet, wenn das Objekt kein abgetrenntes Objekt sein sollte. Möglicherweise möchten Sie den Code lieber werfen lassen, PersistenceException
damit er schnell fehlschlägt.
Obwohl die Spezifikation unklar ist , persist()
kann dies @GeneratedValue
@Id
für ein Objekt festgelegt werden. merge()
muss jedoch ein Objekt mit dem @Id
bereits generierten haben.
merge()
muss jedoch ein Objekt mit dem @Id
bereits generierten haben . ". Wenn der EntityManager keinen Wert für das Feld der Objekt-ID findet, wird er in der Datenbank beibehalten (eingefügt).
Einige weitere Details zur Zusammenführung, die Ihnen bei der Verwendung der Zusammenführung helfen, bleiben bestehen:
Die Rückgabe einer anderen verwalteten Instanz als der ursprünglichen Entität ist ein wichtiger Bestandteil des Zusammenführungsprozesses. Wenn im Persistenzkontext bereits eine Entitätsinstanz mit demselben Bezeichner vorhanden ist, überschreibt der Anbieter seinen Status mit dem Status der zusammengeführten Entität. Die bereits vorhandene verwaltete Version muss jedoch an den Client zurückgegeben werden, damit dies möglich ist benutzt. Wenn der Anbieter die Employee-Instanz im Persistenzkontext nicht aktualisiert hat, werden alle Verweise auf diese Instanz nicht mehr mit dem neuen Status vereinbar, der zusammengeführt wird.
Wenn merge () für eine neue Entität aufgerufen wird, verhält es sich ähnlich wie die persist () -Operation. Es fügt die Entität dem Persistenzkontext hinzu, aber anstatt die ursprüngliche Entitätsinstanz hinzuzufügen, erstellt es eine neue Kopie und verwaltet stattdessen diese Instanz. Die durch die Operation merge () erstellte Kopie bleibt bestehen, als ob die Methode persist () darauf aufgerufen worden wäre.
Bei Vorhandensein von Beziehungen versucht die Operation merge (), die verwaltete Entität so zu aktualisieren, dass sie auf verwaltete Versionen der Entitäten verweist, auf die von der getrennten Entität verwiesen wird. Wenn die Entität eine Beziehung zu einem Objekt hat, das keine dauerhafte Identität hat, ist das Ergebnis der Zusammenführungsoperation undefiniert. Einige Anbieter erlauben möglicherweise, dass die verwaltete Kopie auf das nicht persistente Objekt verweist, während andere möglicherweise sofort eine Ausnahme auslösen. In diesen Fällen kann die Operation merge () optional kaskadiert werden, um das Auftreten einer Ausnahme zu verhindern. Wir werden uns später in diesem Abschnitt mit der Kaskadierung der Operation merge () befassen. Wenn eine zusammengeführte Entität auf eine entfernte Entität verweist, wird eine IllegalArgumentException-Ausnahme ausgelöst.
Lazy-Loading-Beziehungen sind ein Sonderfall bei der Zusammenführung. Wenn eine Lazy-Loading-Beziehung für eine Entität nicht ausgelöst wurde, bevor sie getrennt wurde, wird diese Beziehung beim Zusammenführen der Entität ignoriert. Wenn die Beziehung während der Verwaltung ausgelöst und dann auf Null gesetzt wurde, während die Entität getrennt wurde, wird die Beziehung in der verwalteten Version der Entität ebenfalls während der Zusammenführung gelöscht. "
Alle oben genannten Informationen stammen aus "Pro JPA 2 Mastering the Java ™ Persistence API" von Mike Keith und Merrick Schnicariol. Kapitel 6. Ablösen und Zusammenführen von Abschnitten. Dieses Buch ist eigentlich ein zweites Buch, das von Autoren JPA gewidmet wurde. Dieses neue Buch enthält viele neue Informationen als die früheren. Ich habe wirklich empfohlen, dieses Buch für diejenigen zu lesen, die ernsthaft mit JPA zu tun haben. Es tut mir leid, dass ich meine erste Antwort einstimmig veröffentlicht habe.
Es gibt einige weitere Unterschiede zwischen merge
und persist
(ich werde die bereits hier veröffentlichten noch einmal aufzählen):
D1. merge
macht die übergebene Entität nicht verwaltet, sondern gibt eine andere verwaltete Instanz zurück. persist
Auf der anderen Seite wird die übergebene Entität verwaltet:
//MERGE: passedEntity remains unmanaged, but newEntity will be managed
Entity newEntity = em.merge(passedEntity);
//PERSIST: passedEntity will be managed after this
em.persist(passedEntity);
D2. Wenn Sie eine Entität entfernen und dann entscheiden, die Entität zurückzuhalten, können Sie dies nur mit persist () tun, da merge
eineIllegalArgumentException
.
D3. Wenn Sie sich entschieden haben, Ihre IDs manuell zu verwalten (z. B. mithilfe von UUIDs), merge
löst eine Operation nachfolgende SELECT
Abfragen aus, um nach vorhandenen Entitäten mit dieser ID zu suchenpersist
ohne diese Abfragen zu benötigen.
D4. Es gibt Fälle, in denen Sie dem Code, der Ihren Code aufruft, einfach nicht vertrauen. Um sicherzustellen, dass keine Daten aktualisiert, sondern eingefügt werden, müssen Sie verwenden persist
.
Ich habe lazyLoading-Ausnahmen für meine Entität erhalten, weil ich versucht habe, auf eine faul geladene Sammlung zuzugreifen, die sich in einer Sitzung befand.
Was ich tun würde, war in einer separaten Anfrage, die Entität aus der Sitzung abzurufen und dann zu versuchen, auf eine Sammlung auf meiner JSP-Seite zuzugreifen, was problematisch war.
Um dies zu vermeiden, habe ich dieselbe Entität in meinem Controller aktualisiert und an meinen JSP übergeben, obwohl ich mir vorstelle, dass ich beim erneuten Speichern in der Sitzung auch darauf zugreifen kann SessionScope
und kein a auslösen kannLazyLoadingException
Änderung von Beispiel 2 auslösen kann:
Folgendes hat für mich funktioniert:
// scenario 2 MY WAY
// tran starts
e = new MyEntity();
e = em.merge(e); // re-assign to the same entity "e"
//access e from jsp and it will work dandy!!
Ich fand diese Erklärung aus den Hibernate-Dokumenten aufschlussreich, da sie einen Anwendungsfall enthalten:
Die Verwendung und Semantik von merge () scheint für neue Benutzer verwirrend zu sein. Erstens sollten Sie merge () überhaupt nicht verwenden müssen , solange Sie nicht versuchen, den in einem Entitätsmanager geladenen Objektstatus in einem anderen neuen Entitätsmanager zu verwenden . Einige ganze Anwendungen werden diese Methode niemals verwenden.
Normalerweise wird merge () im folgenden Szenario verwendet:
- Die Anwendung lädt ein Objekt in den ersten Entitätsmanager
- Das Objekt wird an die Präsentationsschicht übergeben
- Einige Änderungen werden am Objekt vorgenommen
- Das Objekt wird an die Geschäftslogikschicht zurückgegeben
- Die Anwendung behält diese Änderungen bei, indem sie merge () in einem zweiten Entitätsmanager aufruft
Hier ist die genaue Semantik von merge ():
- Wenn eine verwaltete Instanz mit derselben Kennung vorhanden ist, die derzeit dem Persistenzkontext zugeordnet ist, kopieren Sie den Status des angegebenen Objekts auf die verwaltete Instanz
- Wenn dem Persistenzkontext derzeit keine verwaltete Instanz zugeordnet ist, versuchen Sie, sie aus der Datenbank zu laden, oder erstellen Sie eine neue verwaltete Instanz
- Die verwaltete Instanz wird zurückgegeben
- Die angegebene Instanz wird nicht mit dem Persistenzkontext verknüpft, sondern bleibt getrennt und wird normalerweise verworfen
Von: http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/objectstate.html
Beim Durchgehen der Antworten fehlen einige Details bezüglich "Cascade" und ID-Generierung. Siehe Frage
Erwähnenswert ist auch, dass Sie separate Cascade
Anmerkungen zum Zusammenführen und Fortbestehen haben können: Cascade.MERGE
undCascade.PERSIST
die nach dem verwendeten Verfahren behandelt werden.
Die Spezifikation ist dein Freund;)
JPA ist unbestreitbar eine große Vereinfachung im Bereich von Unternehmensanwendungen, die auf der Java-Plattform basieren. Als Entwickler, der sich mit den Feinheiten der alten Entity Beans in J2EE auseinandersetzen musste, sehe ich die Aufnahme von JPA in die Java EE-Spezifikationen als einen großen Sprung nach vorne. Während ich mich jedoch eingehender mit den JPA-Details befasse, finde ich Dinge, die nicht so einfach sind. In diesem Artikel beschäftige ich mich mit dem Vergleich der Merge- und Persist-Methoden des EntityManager, deren überlappendes Verhalten nicht nur bei Neulingen Verwirrung stiften kann. Darüber hinaus schlage ich eine Verallgemeinerung vor, bei der beide Methoden als Sonderfälle eines allgemeineren Methodenkombinats betrachtet werden.
Bestehende Einheiten
Im Gegensatz zur Zusammenführungsmethode ist die Persist-Methode ziemlich einfach und intuitiv. Das häufigste Szenario für die Verwendung der Persist-Methode kann wie folgt zusammengefasst werden:
"Eine neu erstellte Instanz der Entitätsklasse wird an die persist-Methode übergeben. Nachdem diese Methode zurückgegeben wurde, wird die Entität verwaltet und zum Einfügen in die Datenbank geplant. Dies kann bei oder vor dem Festschreiben der Transaktion oder beim Aufruf der Flush-Methode geschehen. Wenn die Entität über eine Beziehung, die mit der PERSIST-Kaskadenstrategie markiert ist, auf eine andere Entität verweist, wird dieses Verfahren auch auf diese angewendet. "
Die Spezifikation geht mehr auf Details ein, das Erinnern an sie ist jedoch nicht entscheidend, da diese Details nur mehr oder weniger exotische Situationen abdecken.
Zusammenführen von Einheiten
Im Vergleich zu persist ist die Beschreibung des Zusammenführungsverhaltens nicht so einfach. Es gibt kein Hauptszenario, wie es im Fall von persist der Fall ist, und ein Programmierer muss sich alle Szenarien merken, um einen korrekten Code zu schreiben. Es scheint mir, dass die JPA-Designer eine Methode haben wollten, deren Hauptanliegen darin besteht, getrennte Entitäten zu behandeln (im Gegensatz zu der Persist-Methode, die sich hauptsächlich mit neu erstellten Entitäten befasst). Die Hauptaufgabe der Zusammenführungsmethode besteht darin, den Status von einer zu übertragen Nicht verwaltete Entität (als Argument übergeben) an ihr verwaltetes Gegenstück im Persistenzkontext. Diese Aufgabe gliedert sich jedoch weiter in mehrere Szenarien, die die Verständlichkeit des Verhaltens der Gesamtmethode verschlechtern.
Anstatt Absätze aus der JPA-Spezifikation zu wiederholen, habe ich ein Flussdiagramm erstellt, das das Verhalten der Zusammenführungsmethode schematisch darstellt:
Also, wann sollte ich persist verwenden und wann zusammenführen?
fortdauern
verschmelzen
Szenario X:
Tabelle: Spitter (Eins), Tabelle: Spittles (Viele) (Spittles ist Eigentümer der Beziehung zu einem FK: spitter_id)
Dieses Szenario führt zum Speichern: Der Spitter und beide Spittles, als ob sie demselben Spitter gehören.
Spitter spitter=new Spitter();
Spittle spittle3=new Spittle();
spitter.setUsername("George");
spitter.setPassword("test1234");
spittle3.setSpittle("I love java 2");
spittle3.setSpitter(spitter);
dao.addSpittle(spittle3); // <--persist
Spittle spittle=new Spittle();
spittle.setSpittle("I love java");
spittle.setSpitter(spitter);
dao.saveSpittle(spittle); //<-- merge!!
Szenario Y:
Dies wird den Spitter retten, wird die 2 Spittles retten, aber sie werden nicht auf denselben Spitter verweisen!
Spitter spitter=new Spitter();
Spittle spittle3=new Spittle();
spitter.setUsername("George");
spitter.setPassword("test1234");
spittle3.setSpittle("I love java 2");
spittle3.setSpitter(spitter);
dao.save(spittle3); // <--merge!!
Spittle spittle=new Spittle();
spittle.setSpittle("I love java");
spittle.setSpitter(spitter);
dao.saveSpittle(spittle); //<-- merge!!
Eine weitere Beobachtung:
merge()
kümmert sich nur um eine automatisch generierte ID (getestet auf IDENTITY
und SEQUENCE
), wenn ein Datensatz mit einer solchen ID bereits in Ihrer Tabelle vorhanden ist. In diesem Fall merge()
wird versucht, den Datensatz zu aktualisieren. Wenn jedoch eine ID fehlt oder nicht mit vorhandenen Datensätzen übereinstimmt, merge()
wird sie vollständig ignoriert und eine Datenbank aufgefordert, eine neue zuzuweisen. Dies ist manchmal eine Quelle für viele Fehler. Verwenden Sie diese Option nicht merge()
, um eine ID für einen neuen Datensatz zu erzwingen.
persist()
Auf der anderen Seite können Sie niemals einen Ausweis an ihn weitergeben. Es wird sofort fehlschlagen. In meinem Fall ist es:
Auslöser: org.hibernate.PersistentObjectException: Abgetrennte Entität, die an persist übergeben wurde
hibernate-jpa javadoc hat einen Hinweis:
Wirft : javax.persistence.EntityExistsException - wenn das Unternehmen bereits vorhanden ist . (Wenn die Entität bereits vorhanden ist, wird die EntityExistsException möglicherweise ausgelöst, wenn die Persist-Operation aufgerufen wird, oder die EntityExistsException oder eine andere PersistenceException wird möglicherweise zum Löschen oder Festschreiben ausgelöst.)
persist()
beschwert sich nicht, dass es eine ID hat, es beschwert sich nur, wenn sich bereits etwas mit derselben ID in der Datenbank befindet.
Möglicherweise sind Sie hierher gekommen, um Ratschläge zu erhalten, wann persist und wann merge verwendet werden soll . Ich denke, dass es von der Situation abhängt: Wie wahrscheinlich ist es, dass Sie einen neuen Datensatz erstellen müssen, und wie schwierig ist es, persistente Daten abzurufen.
Nehmen wir an, Sie können einen natürlichen Schlüssel / Bezeichner verwenden.
Daten müssen beibehalten werden, aber hin und wieder ist ein Datensatz vorhanden und eine Aktualisierung ist erforderlich. In diesem Fall können Sie versuchen, eine Persist zu erstellen. Wenn eine EntityExistsException ausgelöst wird, suchen Sie sie und kombinieren die Daten:
try {entityManager.persist (entity)}
catch (EntityExistsException-Ausnahme) {/ * abrufen und zusammenführen * /}
Persistierte Daten müssen aktualisiert werden, aber hin und wieder gibt es noch keinen Datensatz für die Daten. In diesem Fall suchen Sie nach und führen eine Persistenz durch, wenn die Entität fehlt:
entity = entityManager.find (Schlüssel);
if (entity == null) {entityManager.persist (entity); }}
sonst {/ * zusammenführen * /}
Wenn Sie keinen natürlichen Schlüssel / Bezeichner haben, fällt es Ihnen schwerer, herauszufinden, ob die Entität vorhanden ist oder nicht, oder wie Sie sie nachschlagen können.
Die Zusammenführungen können auch auf zwei Arten behandelt werden:
persist (Entität) sollte mit völlig neuen Entitäten verwendet werden, um sie zur Datenbank hinzuzufügen (wenn die Entität bereits in der Datenbank vorhanden ist, wird EntityExistsException ausgelöst).
Merge (Entität) sollte verwendet werden, um die Entität wieder in den Persistenzkontext zu versetzen, wenn die Entität getrennt und geändert wurde.
Wahrscheinlich generiert persist die INSERT-SQL-Anweisung und führt die UPDATE-SQL-Anweisung zusammen (aber ich bin mir nicht sicher).