2

Trying to understand more about Hibernate,I wrote some code which creates some entities and saves them in db and then tries to delete one of the entities.

The mapping file for entity Customer has id generator set to native.I am using postgresql as db.

...
<class name="Customer" table="CUSTOMER">
  <id column="CUSTOMER_ID" name="customer_id"  type="java.lang.Long">
  <generator class="native"/>
  </id>
...

I came across hibernate.NonUniqueObjectException.

 org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [org.me.hibernatestore.Customer#129]

Full stack trace here

I fired up the eclipse debugger and found that the object involved has same address in all the involved methods ..

The relevant part of the code is

public class Main {
        CustomerDao custdao;
        Customer mark;
        public void storeDemo(){
           custdao = DaoFactory.getCustomerDao();
           createCustomers();
           updateEntities();
           deleteCustomer(mark);
        }
        private void createCustomers() {
            mark = new Customer();
            mark.setName("mark");
            mark.setEmailAddress("mark@home");
            mark.setAddress("121,3rd avenue");
            mark.setCity("San Diego");
            mark.setState("CA");
            mark.setCountry("U.S.A");
        }
        private  void updateEntities() {
            Transaction tx = null;
            Session session = HibernateUtil.getCurrentSession();        
            try{
                tx = session.beginTransaction();                
                custdao.saveOrUpdateCustomer(mark);
                tx.commit();
               }catch(RuntimeException e){          
            tx.rollback();
            throw e;
        }
       }
       private void deleteCustomer(Customer cust){
        Transaction tx = null;
        Session session = HibernateUtil.getCurrentSession();        
        try{
            tx = session.beginTransaction();            
            String custName = cust.getName();
            custdao.deleteCustomer(cust);
            tx.commit();            

        }catch(RuntimeException e){         
            tx.rollback();
            throw e;
        }
    }
        public static void main(String[] args)  {
        new Main().storeDemo();

    }
}

With the help of debugger I found the address of object 'mark'

Main.createCustomers(): mark-> Customer@2bc3f5
CustomerDaoImpl.saveOrUpdateCustomer(Customer customer):customer-> Customer@2bc3f5
BaseDaoImpl.saveOrUpdate(T obj):obj-> Customer@2bc3f5

Main.deleteCustomer(Customer customer):customer-> Customer@2bc3f5
CustomerDaoImpl.deleteCustomer(Customer customer):customer-> Customer@2bc3f5
BaseDaoImpl.delete(T obj):obj-> Customer@2bc3f5

Experimenting further,I modified the code and through dao.findById() got a different object with same id and used that in deleteCustomer().This time the code worked without throwing any exception

public class Main {
        CustomerDao custdao;
        Customer mark;
        public void storeDemo(){
           custdao = DaoFactory.getCustomerDao();
           createCustomers();
           updateEntities();
           Long mark_id = mark.getCustomer_id();
           Customer mark2 = getCustomer(mark_id);
           deleteCustomer(mark2);
        }
    private Customer getCustomer(Long id){
        Transaction tx = null;
        Customer cust = null;
        Session session = HibernateUtil.getCurrentSession();

        try{
            tx = session.beginTransaction();
            return custdao.findCustomerById(id);

        }catch(RuntimeException e){         
            throw e;
        }
    }
        ...
}

Can someone explain this behaviour?My understanding about the 'a different object with the same identifier value' part of the error message is fuzzy ..The object as shown in debugger in the first case has same memory address everywhere in the code.Then how can it be a different object?

sincerely

Jim

jimgardener
  • 637
  • 2
  • 10
  • 26
  • Possible duplicate of [Hibernate Error: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session](https://stackoverflow.com/questions/1074081/hibernate-error-org-hibernate-nonuniqueobjectexception-a-different-object-with) – Vadzim May 16 '19 at 19:27

1 Answers1

0

This exception usually occurs when dealing with detached objects. In order to avoid that, you have to get the object and delete it in the same session or reattach it to the session and then delete it. Hope this helps!

Community
  • 1
  • 1
loodakrawa
  • 1,468
  • 14
  • 28