使用Hibernate操作对象的时候报错【update一个对象报的错】

来源:互联网 发布:sql语句导入excel数据 编辑:程序博客网 时间:2024/05/22 00:36

文章来源:http://blog.163.com/chinagujing@yeah/blog/static/170937439201092405558777/


昨天在一个方法中update一个对象的时候报出如下错误:
org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions
去网上查了下,把update方法换成了merge方法后问题解决。


于是在此把对对象的相关操作和概念总结一下。
首先,在hibernate中对象有四种状态:
瞬时状态:一个新建的对象是处于瞬时状态的,即不和数据库中的任意表有关联。
持久化状态:这个对象是包含数据库同一性的实体。
移除状态:一个对象如果已经被计划在一个工作单元结束时删除,它就是处于移除状态。
脱管状态:对象状态不与数据库状态同步,但仍包含持久化数据。
然后在介绍Session中几个常用方法之前,还要再提一下脏对象的相关概念。hibernate有个策略,用来侦测哪个持久化对象已经被应用程序修改,被称为自动脏检查。一个被修改过的对象还没有传播到数据库之前都被认为是脏的。

1.save方法
将瞬时实例持久化,此时它与当前的session和持久化上下文都建立了联系。

2.get/load方法
这两个方法都是从数据库中取得持久化对象,在持久化上下文关闭后变为脱管状态。其区别在于如果数据库中不存在指定标识符的行,get会返回null,而load会抛出ObjectNotFoundException。

3.delete方法
调用后对象变为移除状态,session关闭后变为瞬时状态。

4.replicate方法
用于从一个数据库中获取对象并负责到另一个数据库。

5.update/lock方法
对象在传递到update方法之前是否被修改没有关系,update方法把这个脱管实例附到一个新的session及持久化上下文,hibernate始终将这个对象当做脏对象来处理。而在调用lock之前对对象的修改不会传播到数据库。

6.merge方法
调用merge方法的时候,hibernate会检查在持久化上下文中的持久化实例是否和脱管实例具有相同的标识符。如果有,把脱管实例的状态负责到持久化实例中;如果没有,就从数据库中加载,然后把脱管实例和获取的对象状态合并;如果数据库中没有查到结果,就创建新的持久化实例,把脱管实例的状态复制到新实例,插入到数据库中,并通过merge()操作返回。


0 0