Search code examples
hibernatehibernate-mapping

hibernate NonUniqueObjectException: a different object with the same identifier value was already associated with the session:


My Code:

I am trying to do either update/insert. It gets inserted properly, only problem is when I try to update it gives below error message.

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";
}

Error:

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 have used

session.merge(accountDetails)

there is no error, but it always does insert data into db instead of update.


Solution

  • 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";
        }
    

    Removed @GeneratedValue from my dto, since value was coming from UI.

    Here is the good article, how to use MERGE/UPDATE