2016-05-12 14 views
0

Ich verstehe, dass wann NonUniqueObjectException auftritt und warum es auftritt.Wenn Hibernate entfernt wird, werden gelöschte Objekte aus dem Speicher entfernt NonUniqueObjectException

Ich sah viele Beispiele im Internet für NonUniqueObjectException, jeder hat das gleiche. Objekt wird zuerst von Sitzung1 getrennt, also wird Sitzung1 geschlossen und ebenfalls gelöscht, und dann Objekt mit derselben Kennung ist Update oder SaveOrUpdate in Sitzung2.

Code-Snippet:

Session session = sessionFactory1.openSession(); 
Transaction tx = session.beginTransaction(); 
Item item = (Item) session.get(Item.class, new Long(1234)); 
tx.commit(); 
session.close(); // end of first session, item is detached 
item.getId();// The database identity is "1234" item.setDescription("my new description"); 
Session session2 = sessionFactory.openSession(); 
Transaction tx2 = session2.beginTransaction(); 
Item item2 = (Item) session2.get(Item.class, new Long(1234)); 
session2.update(item);// Throws NonUniqueObjectException 
tx2.commit(); 
session2.close(); 

Meine Frage ist, selbst wenn seesion1 geschlossen ist, warum hat Hibernate freistehendes Objekt in session1 hält, obwohl es nicht verwalten. Wann wird das gesamte Objekt aus der Sitzung1 entfernt? verstehen

+0

Bitte kopieren Sie den Code, den Sie fragen, in diese Frage zusätzlich zum Verlinken (Ihre Frage bleibt also verständlich, selbst wenn diese externe Seite ausfällt und die Leute keine externe Seite besuchen müssen, um Ihre Frage zu beantworten) – meriton

+0

Code-Snippet hinzugefügt – Dave

Antwort

1

Hibernate funktioniert nicht einen Verweis auf ein freistehendes Objekt halten, das heißt frei stehende Objekte sind nicht Teil einer Sitzung, und ihre Garbage Collection in keiner Weise behindert wird.

Der Grund für eine NonUniqueObjectException ist, dass zwei verschiedene Objekte für dieselbe Datenbankzeile derselben Sitzung zugeordnet wurden. Das ist schlecht, weil Hibernate Änderungen an Objekten in der Sitzung automatisch erkennt und diese Änderungen zurück in die Datenbank schreibt. Wenn sich mehrere Objekte für dieselbe Zeile in derselben Sitzung befinden, ist unklar, welcher Objektstatus geschrieben werden soll. Da dies zu schwer zu findenden Fehlern führen würde, lehnt Hibernate eine solche Situation ab.

Normalerweise stellt Hibernate sicher, dass alle Abfragen für eine Zeile in einer bestimmten Sitzung das gleiche Objekt zurückgeben, so dass diese Situation nicht auftreten kann. Wenn Sie jedoch ein Objekt aus einer anderen Sitzung mit einer neuen Sitzung verwenden, wird es der neuen Sitzung zugeordnet, was fehlschlagen kann, wenn die neue Sitzung bereits ein Objekt für diese Zeile enthält. Diese

ist, warum der neuere EntityManager API nicht mehr verfügt über ein update Verfahren, die ein bereits vorhandenes Objekt mit der Sitzung assoziiert, aber eine merge Methode, die kopiert den Inhalt des Objekts in das Objekt mit der Sitzung verknüpft ist.

1

zu, schauen Sie hier:

http://3.bp.blogspot.com/-katvFbmjewU/Tqv4Ble7_QI/AAAAAAAAAJE/odH15Qm9-hs/s1600/object-states.JPG

Item item2 = (Item) session2.get(Item.class, new Long(1234)); 

Dies wird dann auch in persistenten Zustand item2 mit der ID 1234 im session2.

session2.update(item); 

item ist in abgenommenen Zustand und update() wird item in persistenten Zustand auf session2 drehen >>> Hibernate wirft NonUniqueObjectException, weil es zwei Objekte in der gleichen Sitzung Item mit gleichen ID sind!

Machen Sie es wie folgt aus:

Session session2 = sessionFactory.openSession(); 
Transaction tx2 = session2.beginTransaction(); 
Item item2 = (Item) session2.get(Item.class, new Long(1234)); 
item2.setDescription("my new description"); 
session2.update(item2); 
tx2.commit(); 
+0

Bitte korrigieren Sie mich, wenn ich falsch liege, wenn ich session1.close() mache, wird auch session1.clear() aufgerufen. Also, wenn session1 gelöscht wird, dann sollte Hibernate kein Objekt im Speicher finden.Wenn der Ruhezustand das Objekt nicht aus dem Speicher entfernt und nur die Sitzung trennt, ist das obige Verhalten verständlich. – Dave

+0

Ja, aber Session2 ist eine neue Sitzung. session2 weiß nichts über das 'item' Objekt, also versucht es' item' in der Datenbank hinzuzufügen und es wird fehlschlagen ... 'item' wird von allen Sitzungen getrennt,' item2' wird an 'session2' angehängt. – Guillaume

+0

Edited my Antworten. – Guillaume

Verwandte Themen