项目中使用Hibernate时报了一个异常:org.hibernate.NonUniqueObjectException;经从网上查找资料得知,同一个session里面有了两个相同标识可是是不一样实体.即2个不一样的对象关联到了同一个标志位。java
验证代码以下:sql
@Test public void add() { Session session = SessionFactory.getSession(); Transaction tr = session.beginTransaction(); // ---------------------------------------------- Person p1 = (Person) session.get(Person.class, 0); Person p2 = new Person(); p2.setId(0); p2.setName("username" + p1.getName()); session.update(p2); // ---------------------------------------------- tr.commit(); SessionFactory.closeSession(); }
执行报出异常:数据库
解决方案:使用session.merge()方法代替update()方法。session
当调用update或saveOrUpdate操做时,抛出了异常信息“org.hibernate.NonUniqueObjectException”,不是“独一无二”的对象。为何会抛出这个错误呢?上面的person2调用了get方法,因此person2是一个持久化对象,当在session尚未关闭的时候对person2作的任何修改,都会保存到数据库中;person要执行更新操做,但因为它是一个脱管对象,那么就须要跟数据库从新取得联系,须要从数据库获取数据,hibernate会查找当前是否关于这个对象的副本,恰好有个person2(但又不知person2是否修改了且保存到了数据库),与其保存这可能没用的数据,还不如直接报错来得直接。这里调用update和saveOrUpdate相似。.net
还有update与merge的一点不一样是:update是直接发出“sql update”语句,而merge会先发出“sql select”语句,若是没有查询到结果,那么执行save操做,若是查询到相关结果,则判断对应字段是否有发生改变,若是改变了,则发出“sql update”语句,不然什么也不作。这一方面,merge就和saveOrUpdate相同。hibernate
参考文章:code
http://blog.csdn.net/zhongxianyao/article/details/12294011对象
http://www.simplecodestuffs.com/difference-between-update-and-merge-methods-in-hibernate/blog