Mon code:
J'essaie de faire une mise à jour/insertion. Il est inséré correctement, le seul problème est lorsque j'essaie de le mettre à jour, il donne un message d'erreur ci-dessous.
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";
}
Erreur:
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:
J'ai utilisé
session.merge (accountDetails)
il n'y a pas d'erreur, mais il insère toujours des données dans db au lieu de mettre à jour.
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";
}
Suppression de @GeneratedValue de mon dto, car la valeur provenait de l'interface utilisateur.
Voici le bon article, comment utiliser MERGE/UPDATE
J'ai eu cette erreur lors de l'ouverture de deux sessions. Une session pour un utilisateur et une autre session pour un objet dont la clé primaire est une clé étrangère de l'utilisateur. Avec cela, les deux sessions ont la même clé primaire ou identifiant. J'ai résolu cela par session.clear avant session.update (type).
public T update(T type) { Session session = getSession(); session.clear(); session.update( type ); session.flush(); return type; }
Essayez d'utiliser une seule session comme suggéré par lalit.
Le code a été réduit comme ci-dessous.
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";
}
Réponse assez tardive mais ceux qui recherchent la même erreur peuvent le savoir. Cela a fonctionné pour moi. Lorsque vous enregistrez des données dans une boucle avant la validation, utilisez session.flush () et après la validation, utilisez session.clear ().
session.flush();
session.beginTransaction().commit();
session.clear();