2014-09-22 1 views
11

Meinen Code:Hibernate NonUniqueObjectException: ein anderes Objekt mit dem gleichen Kennungswert wurde bereits mit der Sitzung verknüpft:

Ich versuche, entweder Update/Insert zu tun. Es wird richtig eingefügt, nur Problem, wenn ich versuche, es zu aktualisieren gibt unten Fehlermeldung.

private String sessionType=null; 
public String getAccountsDetails(List<Account> accountList) {  
    Session session = sessionFactory.openSession(); 
    for (Account account : accountList) { 
     AccountDetails accountDetails = new AccountDetails(); 
     accountDetails.setAccountsId(Long.parseLong(account.getId())); 
     accountDetails.setAccounttype(account.getAccountType().value()); 
     Query query = session.createQuery("from QBAccounts qba where qba.accountsId=:accId"); 
     List<AccountDetails> queryList = query.setParameter("accId", accountDetails.getAccountsId()).list(); 
     if(queryList.size()>0){   
      session.update(accountDetails); 
     }else{ 
      session.save(accountDetails); 
     } 
    } 
    session.flush(); 
    session.beginTransaction().commit(); 
    session.clear(); 
    session.close();   
    return "Successfully data updated into table"; 
} 

Fehler:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.trinet.mulesoft.quickbooks.dto.AccountDetails#0] 
    at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:638) 
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:305) 
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:246)   

EDIT 2:

I

session.merge(accountDetails)

verwendet haben

kein Fehler vorhanden ist, aber es funktioniert immer Daten in db einfügen statt der Aktualisierung.

+2

Warum verwenden Sie zwei verschiedene Sitzungen? Sie können in derselben Sitzung speichern und aktualisieren, es sei denn, ich verpasse etwas. Sehen Sie, ob dies hilft http://tech.lalitbhatt.net/2014/07/hibernate-persistent-context-and-session.html – lalit

+0

@lalit, ich versuchte mit der gleichen Sitzung, wie ich informiert, es funktioniert gut für die Einfügung für die das erste Mal, dann der nächste Schritt ist Update, es wirft denselben Fehler. Früher habe ich eine veraltete Objektstatusausnahme bekommen, also habe ich eine andere Sitzung benutzt. Oben aktualisiert. – TechFind

Antwort

5
public String getAccountsDetails(AccountDetails accountDetails) { 
     System.out.println("accountDetails.accoundId-->"+accountDetails.getAccountsId()); 
     Session session = sessionFactory.openSession(); 
     Query query = session.createQuery("from QBAccounts qba where qba.accountsId=:accId"); 
     List<AccountDetails> queryList = query.setParameter("accId", accountDetails.getAccountsId()).list(); 
     session.close(); 
     Session session2 = sessionFactory.openSession(); 
//   session.saveOrUpdate(accountDetails); 
     try{ 
      if(queryList.size()>0){     
       session2.beginTransaction(); 
       /* 
       * comment below line-50,51 to use update instead of merge, and uncomment line 53 
       */ 
       AccountDetails acDet = (AccountDetails) session2.get(AccountDetails.class, new Long(1));//line 50 
       session2.merge(accountDetails);//line 51 
       System.out.println("acDet-->"+acDet+" --accountDetails-> "+accountDetails);//line 52 
//    session2.update(accountDetails);//line 53 
      }else{ 
       session2.beginTransaction(); 
       session2.save(accountDetails); 
      } 
     }catch(DIRException e){ 
      session2.getTransaction().rollback(); 
      System.out.println("Getting Exception : " + e.getLocalizedMessage()); 
     }finally{ 
      session2.getTransaction().commit(); 
      session2.close(); 
     } 
     return "Successfully data updated into table"; 
    } 

entfernt @GeneratedValue von meinem dto, da Wert von UI kommen würde.

Hier ist der gute Artikel, wie MERGE/UPDATE

+0

Link zu artricle ist tot – Macilias

4

Versuchen Sie, nur eine Sitzung zu verwenden, wie von lalit vorgeschlagen.

Der Code wurde wie folgt reduziert.

private String sessionType=null; 
public String getAccountsDetails(List<Account> accountList) {  
    Session session = sessionFactory.openSession(); 

    for (Account account : accountList) { 
     AccountDetails accountDetails = new AccountDetails(); 
     accountDetails.setAccountsId(Long.parseLong(account.getId())); 
     accountDetails.setAccounttype(account.getAccountType().value()); 
     Query query = session.createQuery("from QBAccounts qba where qba.accountsId=:accId"); 
     List<AccountDetails> queryList = query.setParameter("accId", accountDetails.getAccountsId()).list(); 
     if(queryList.size()>0){   
      session.update(accountDetails); 
      sessionType = "update"; 
     }else{ 
      session.save(accountDetails); 
      sessionType = "save"; 
     } 
    } 
     session.flush(); 
     session.beginTransaction().commit(); 
     session.clear(); 
     session.close(); 


    return "Successfully data updated into table"; 
} 
+0

Ich versuchte mit der gleichen Sitzung, wie ich informiert, es funktioniert gut für die Einfügung zum ersten Mal, dann ist der nächste Schritt Update, es wirft den gleichen Fehler. Früher habe ich eine veraltete Objektstatusausnahme bekommen, also habe ich eine andere Sitzung benutzt. – TechFind

1

Ganz späte Antwort zu verwenden, aber andere, die für den gleichen Fehler suchen können wissen. Das hat für mich funktioniert. Wenn Sie Daten in einer Schleife vor dem Festschreiben speichern, verwenden Sie session.flush() und nach dem Festschreiben verwenden Sie session.clear().

session.flush(); 
    session.beginTransaction().commit(); 
    session.clear(); 
5

Ich hatte diesen Fehler beim Öffnen von zwei Sitzungen. Eine Sitzung für einen Benutzer und eine weitere Sitzung für ein Objekt, dessen Primärschlüssel ein Fremdschlüssel von Benutzer ist. Damit haben die beiden Sitzungen den gleichen Primärschlüssel oder Identifikator. Ich löste dies durch session.clear vor session.update (type).

public T update(T type) { Session session = getSession(); session.clear(); session.update(type); session.flush(); return type; }

Verwandte Themen