org.hibernate.NonUniqueObjectException示例

时间:2013-09-09 15:24:40

标签: java hibernate orm

我阅读了很多有关此异常的信息,但对我来说非常困难。

你能写出最简单的例子,会有这个例外吗?

2 个答案:

答案 0 :(得分:0)

当您尝试使用以下命令更新实体时会发生:

session.saveOrUpdate(entity);

这是因为您尝试更新的实体与数据库中的实体具有相同的ID或PK,实际上它更喜欢使用merge而不是saveOrUpdate:

session.merge(entity);

以下是此例外的完整示例:

        Person person = new Person();
        person.setName("NAME");

        Session session = sessionFactory.openSession();
        Transaction transaction1 = session.beginTransaction();
        session.persist(person);
        transaction1.commit();
        session.close();

        person.setName("NEW NAME");

        session = sessionFactory.openSession();
        Transaction transaction2 = session.beginTransaction();
        try {

            // Here the exception will be thrown.
            session.saveOrUpdate(person);

            transaction2.commit();
        } catch (NonUniqueObjectException ex) {
            ex.printStackTrace();
        }
        session.close();

答案 1 :(得分:0)

它正在发生,因为hibernate使用session作为其第一级缓存,如果我们已经将该对象置于分离状态,并且我们再次尝试在具有相应id的另一个会话中获取该对象并且想要更新同一对象,我们将获得此异常

最好使用merge()方法而不是更新。

    Session session = sessionFactory.openSession();
    Transaction transaction1 = session.beginTransaction();
    Person person = new Person();
    person.setName("NAME");
    person.setId(1);//primary key column.
    session.save(person);//making person object persistent.
    transaction1.commit();
    person.setName("some another name");//modifying detached object 

    Session session2 = sessionFactory.openSession();
    Transaction transaction2 = session2.beginTransaction();
    Person updatedPerson=(Person)session2.get(Person.class,1);//now same object with persistent state attached to session2.
     //session.update(person);//will throw exception because update will try to reattach person object to session2 and already one persistent object with same identifier  updatedPerson object existed in session2 so it will throw this exception.

     session2.merge(person);//it will execute fine.
     transation2.commit();
     session2.close();