2013-05-31 6 views
5

Ich verwende den JPA EntityManager, um einige Operationen auszuführen, und eine dieser Operationen ersetzt eine Entität durch eine andere Entität, die die gleiche @Id hat. Also, mit einer oldObject und einer newObject, was ist der beste Weg, um die oldObject zu entfernen und durch die newObject ersetzen?Die beste Methode zum Ersetzen einer Entität mit EntityManager

Hier einige Code ist, das nicht funktioniert:

try 
{ 
    entityManager.getTransaction().begin(); 
    entityManager.remove(oldObject); 
    entityManager.persist(newObject); 
    entityManager.getTransaction().commit(); 
} 
catch (PersistenceException persistExc) 
{ 
    entityManager.getTransaction().rollback(); 
    // do some stuff 
} 

Dieser Code wird die folgende Ausnahme:

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.depressio.SomeObject 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1215) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1148) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1154) 
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:678) 

Nun, natürlich funktioniert es OK, wenn statt der Einheit zu entfernen, ich habe gerade Aktualisieren Sie die Felder, die sich geändert haben. Ich bekomme jedoch nur das neue Objekt (das UI wirft es mir via REST), so dass ich wirklich keine Ahnung habe, welche Felder sich geändert haben, also müsste ich jedes Feld aktualisieren. Wenn es eine Menge Felder gibt, ist das nicht ideal.

Ich denke, ich bin ein wenig verwirrt darüber, wie man eigentlich ein Löschen richtig macht. Ich dachte EntityManager.remove war der richtige Weg, aber ich denke nicht.

Vielen Dank im Voraus!

Edit 1: Ich finde, ich sollte beachten, dass oldObject.id == newObject.id. Die id wird durch eine @SequenceGenerator generiert. Darf ich Objekte mit Bezeichnern beibehalten, wenn deren Bezeichner bereits mit einem Generator versehen ist?

Edit 2: Laut der top upvoted Antwort here, weil die @Id ist bereits definiert und es ist ein automatisch generiertes Feld, Hibernate ist es losgelöst. Jetzt weiß ich warum Ich bekomme die Ausnahme, aber die Lösung ist immer noch unklar.

Antwort

4

Das ist, was EntityManager.merge() tut. Übergeben Sie ihr die neue, losgelöste Entität, und sie wird ihren Zustand mit der alten, verbundenen Entität verbinden. Das losgelöste Gebilde wird losgelöst bleiben, und das alte Gebilde bleibt verbunden, aber sein Zustand wird durch den Zustand des neuen, freistehenden Gebildes ersetzt.

+0

Oh Gott, das ist peinlich. Aus irgendeinem Grund ging ich davon aus, dass "Zusammenführen" nur mit angehängten Entitäten funktioniert, nicht mit getrennten Entitäten. Ich denke, es kann für beide funktionieren, nicht wahr? Wie auch immer, das löst das Problem ... so dumm von mir. Vielen Dank! – Depressio

+0

Das Zusammenführen einer angehängten Entität bewirkt nichts, außer dass die Zusammenführung in Zuordnungen verzweigt wird, die mit der Kaskade MERGE oder ALL gekennzeichnet sind. –

+0

Was passiert, wenn ich die angehängte Entität modifiziere? Muss ich sogar zusammenführen, da es angehängt ist? Ich habe den Eindruck, nein, ich nicht. – Depressio

Verwandte Themen