Hibernate通过update来处理游离状态对象

摘自圣思园hibernate18. 领域对象的三种状态深入详解- 25分钟

上一篇文章中讲到hibernate中对象的三种状态。
http://alleni123.iteye.com/admin/blogs/1977132

这里要说的就是通过update语句对游离状态进行持久化。在开发中是比较常用的一个方法。


先看一下hibernate文档对update方法的说明:

void update(Object object)

[color=darkblue] Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown. This operation cascades to associated instances if the association is mapped with cascade="save-update".[/color]

要理解的是中间那句"If there is a persistent instance with the same identifier, an exception is thrown"
这个意思其实是说, 如果我们执行
User u=new User(1,"allen");
User u2=(User)session.get(User.class,1);
session.update(u);

此时会抛出异常:
[color=red]Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.lj.zhang.User#1]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:697)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:296)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:241)
at org.hibernate.event.internal.DefaultUpdateEventListener.performSaveOrUpdate(DefaultUpdateEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireUpdate(SessionImpl.java:786)
at org.hibernate.internal.SessionImpl.update(SessionImpl.java:778)
at org.hibernate.internal.SessionImpl.update(SessionImpl.java:774)[/color]

这里看一下StatefulPersistenceContext的源码:
/**
* Attemps to check whether the given key represents an entity already loaded with the current session.
* @param object The entity reference against which to perform the uniqueness check
**/

public void checkUniqueness(EntityKey key, Object object) { //这里的参数是1和我们自定义的User对象。
Object entity=getEntity(key), //Object entity=getEntity(key)执行之后entity被赋予了get获取的那个User对象,该对象被从session缓存中提取出来。
if(entity==object)
{ throw new AssertionFailure ("object already associated, but no entry was found");}
if(entity!=null){//由于entity!=null成立, 于是抛出NonUniqueObjectException。
throw new NonUniqueObjectException(key.getIdentifier(), key.getEntityName());
}

}



[color=darkred]也就是说, 当我们要对持久化对象进行update(既更新数据库对象时),我们不应该通过get或者load从数据库读取该id的对象到session缓存中。[/color]

-Session的update()方法完成以下操作:
1. 把User对象重新加入到Session缓存中,使它变为持久化对象。
2. 计划执行一个update语句。 值得注意的是,Session只有在清理缓存的时候才会执行update语句,并且在执行时才会把User对象当前的属性值组装到update语句中。 因此,即使程序中多次修改了User对象的属性,在清理缓存时只会执行一次update语句。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值