Hibernate 疑难异常及处理

来源:互联网 发布:淘宝什么时候搞大打折 编辑:程序博客网 时间:2024/06/08 12:30

本文转载自:http://lovelyvictory.blog.163.com/blog/static/436230572009111411620304/

 

以下是我在网上找的一些资料,希望能给处于困惑当中的人一些帮助。

使用一对多和多对多映射的时候要小心一些

Hibernate 疑难异常及处理

1、a different object with the same identifier value was already associated with the session。

  错误原因:在hibernate中同一个session里面有了两个相同标识但是是不同实体。

  解决方法一:session.clean()

  PS:如果在clean操作后面又进行了saveOrUpdate(object)等改变数据状态的操作,有可能会报出"Found two representations of same collection"异常。

  解决方法二:session.refresh(object)

  PS:当object不是数据库中已有数据的对象的时候,不能使用session.refresh(object)因为该方法是从hibernate的session中去重新取object,如果session中没有这个对象,则会报错所以当你使用saveOrUpdate(object)之前还需要判断一下。

  解决方法三:session.merge(object)

  PS:Hibernate里面自带的方法,推荐使用。

2、Found two representations of same collection

  错误原因:见1。

  解决方法:session.merge(object)

以上两中异常经常出现在一对多映射和多对多映射中

 

save,update,saveOrUpdate的区别:
session.save
1.在session内部缓存中查找待保存对象,即使数据相对以前状态已经发生变化。也将在稍后事务提交时,由脏数据

检查过程加以判定。(有点不懂)
2。如果实体类实现了lifecycle 接口,则调用待保存对象的onsave 方法
3.如果实体类实现了validateble 接口,则调用其validate() 方法。
4。调用对应拦截器的Interceptor.onSave 方法(如果有)
5。构造insert sql 并执行
6。记录插入成功,user.id属性被设定为insert操作返回的新纪录id值。
7。将user 对象放入内部缓存。
8。最后,如果存在级联关系,对级联关系进行递归处理。
session.update
1.首先,根据代更新实体对象的key ,在当前session的内部缓存中进行查找。如果发现,则认为当前实体对象已经

处于persistent 状态。
2。初始化实体对象的状态信息(作为以后脏数据检查的依据),并将其纳入内部缓存。
   (这里并没有发送update sql ) ,update sql 在session.flush方法中执行。
session.saveorupdate
1.首先在session 内部缓存中进行查找,发现则直接返回。
2。执行实体类对应的Interceptor.isUnsaved 方法(如果有),判断对象是否为未保存状态。
3。根据upsaved-value判断对象是否处于未保存状态。
4。如果对象未保存(Transient状态),则调用save 方法。
5。如果为已保存(Detached),调用update 方法将对象与session 重新关联。
saveOrUpdate 实际是save 和update 方法的组合应用。
当前数据是transient 状态,我们应该调用save 方法,如果是detached 状态,则应该先通过session.update方法

更新。
使用saveOrUpdate 方法后,就不用判断当前对象的状态了。