2010-08-24 1 views
14

Mögliche Duplizieren:
Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the sessionHibernate: anderes Objekt mit dem gleichen Kennungswert wurde bereits mit der Sitzung verknüpft

, wenn ich die DAO.update (userbean) verwenden, session.SaveOrUpdate(e); die werfen Ausnahme: Unterschiedliches Objekt mit demselben Bezeichnerwert war bereits mit der Sitzung verknüpft

Die Funktion ist wie folgt:

public E save(E e) { 
    Session session = null; 
    try { 
     session = sessionFactory.openSession(); 
     log.debug("session="+session.hashCode()+" save "+e); 
     session.SaveOrUpdate(e); //here throws exception 
     session.flush(); 
    } 
    catch (Exception e1) { 
     log.err("Cannot open hibernate session "+ e1.getMessage()+" cause : "+e1.getCause()); 
     e1.printStackTrace(); 
    } 
    finally { if (session != null) session.close(); session = null;} 
    return e ; 
} 

die userbean ist eine Instanz der Klasse UserBean

public class UserBean{ 
    private List<GroupBean> groups = new ArrayList<GroupBean>(); 
    private List<RoleBean> roles = new ArrayList<RoleBean>(); 
} 

public class GroupBean{ 
private List<RoleBean> roles = new ArrayList<RoleBean>(); 
} 

jeder groupbean eine Liste von Rollen hat, die nicht verändert werden.

in Datenbank, Gruppen- und Rollen ist many-to-many-Mapping,

zum Beispiel

wir haben ein groupbean # 1, es Rollen: rolebean # 1, rolebean # 2;

groupbean # 2, welche Rollen sind rollebean # 1.

jetzt habe ich eine neue userbean # 1 zu erstellen, es ist Gruppen groupbean # 1 ist und wenn ich die rolebean # 1 bis userbean # 1, wird es wirft die Ausnahme wie der Titel descript

Ich sehe hinzufügen möchten und die server.log, finden, dass, wenn ich Benutzer DAO.save, die saveOrUpdate Reihenfolge ist:

userbean#1 
|---|-----------***userbean.groups 
|  |  groupbean#1 
|  |   groupbean.roles 
|  |    rolebean#1 # save relebean#1 the first time 
|  |    ---done rolebean#1 
|  |   ------done all rolebeans of group.roles 
|  |  ---done groupbean#1 
|  |-----------done all groupbeans of userbean.groups 
|---|-----------***userbean.roles 
    |  rolebean#1   # save rolebean#1 the second time, and throws exception here! 
    |  ----done rolebean#1 
    |  ..... 
    |-----------done all rolebeans of userbean.roles 

die Ursache für die Ausnahme ist rolebean # 1 wurde zweimal in einer Sitzung gespeichert, und ihre Identität ist die gleiche .

In der Funktion speichern (E e): Wenn ich

session.merge(e); 

session.SaveOrUpdate(e); 
ersetzen verwenden

wird keine Ausnahme werfen, aber die rolebean # 1 auf userbean # 1

nicht assocaited

kann jemand einige Vorschläge dazu geben?

Antwort

27

Es wäre einfacher, die genaue Ursache zu identifizieren, wenn wir den Code sehen, dem Sie sowohl dem Benutzer als auch der Gruppe den Role Bean zuweisen.

Im Allgemeinen sagt uns die Ausnahme, dass es zwei Versionen dieser Rollen-Bean (zwei Instanzen) gibt. Der erste wird aktualisiert, dann trifft Hibernate auf den zweiten und erkennt, dass es sich um denselben Bezeichner handelt, jedoch um eine andere Version der Rolle.

Hibernate ist nicht sicher, was richtig ist, und unter saveOrUpdate wird eine Ausnahme ausgelöst, die Sie darüber informiert.

Der Vertrag von Merge funktioniert anders, da er davon ausgeht, dass Sie ihn erneut speichern möchten (d. H., füge alle meine Änderungen zusammen), und wird somit die zweite Version wieder anfügen, alle Änderungen zusammenführen und alle Aktualisierungen speichern.

Ich habe über SaveOrUpdate vs Merge mit etwas mehr Details gebloggt, um zu erklären, was los ist.

Wenn Sie bei SaveOrUpdate bleiben möchten, müssen Sie herausfinden, was Sie in der Zuweisung tun, wodurch eine andere Instanz der Rolle der Rollensammlung des Benutzers im Vergleich zu den Gruppen zugewiesen wird.

Andernfalls, wenn die Auswirkungen der Zusammenführung für Sie arbeiten (die in Übereinstimmung mit dem JPA-Standard ist), dann verwenden Sie es.

Verwandte Themen