понимание NonUniqueObjectException в спящем режиме - PullRequest
2 голосов
/ 28 июля 2011

Пытаясь понять больше о Hibernate, я написал некоторый код, который создает некоторые сущности и сохраняет их в БД, а затем пытается удалить одну из сущностей.

В файле сопоставления для сущности Customer установлен генератор идентификаторов, равныйnative.Я использую postgresql в качестве базы данных.

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

Я столкнулся с hibernate.NonUniqueObjectException.

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

Полная трассировка стека здесь

Я запустил отладчик eclipse и обнаружил, что соответствующий объект имеет один и тот же адрес во всех задействованных методах.

Соответствующая часть кода

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();

    }
}

С помощью отладчика Iнашел адрес объекта '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

Экспериментируя далее, я изменил код и через dao.findById () получил другой объект с тем же идентификатором и использовал его в deleteCustomer (). На этот раз кодработал без каких-либо исключений

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

Может кто-нибудь объяснить это поведение? Мое понимание о ' другом объекте с тем же значением идентификатора 'часть сообщения об ошибке нечеткая .. Объект, показанный в отладчике в первом случае, имеет одинаковый адрес памяти везде в коде. Тогда как это может быть другой объект?

искренне

Jim

1 Ответ

0 голосов
/ 18 ноября 2011

Это исключение обычно возникает при работе с отсоединенными объектами .Чтобы избежать этого, вы должны получить объект и удалить его в том же сеансе или повторно присоединить его к сеансу , а затем удалить его.Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...