随笔 - 37  文章 - 14  trackbacks - 0
<2007年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿

随笔分类

随笔档案

文章分类

相关链接

搜索

  •  

最新评论

阅读排行榜

评论排行榜

unsave-value:用来控制是save还是update对象。
当你显式的使用session.save()或者session.update()操作一个对象的时候,实际上是用不到unsaved-value的。某些情况下(父子表关联保存),当你在程序中并没有显式的使用save或者update一个持久对象,那么Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象,是一个尚未被持久化过的内存临时对象。例如:

 1Session session = ;   
 2Transaction tx = ;   
 3  
 4Parent parent = (Parent) session.load(Parent.class, id);   
 5  
 6Child child = new Child();   
 7child.setParent(parent);   
 8child.setName("sun");   
 9  
10parent.addChild(child);   
11s.update(parent);   
12  
13s.flush();   
14tx.commit();   
15s.close();  

在上例中,程序并没有显式的session.save(child); 那么Hibernate需要知道child究竟是一个临时对象,还是已经在数据库中有的持久对象。如果child是一个新创建的临时对象(本例中就是这种情况),那么Hibernate应该自动产生session.save(child)这样的操作,如果child是已经在数据库中有的持久对象,那么Hibernate应该自动产生session.update(child)这样的操作。

因此我们需要暗示一下Hibernate,究竟child对象应该对它自动save还是update。在上例中,显然我们应该暗示Hibernate对child自动save,而不是自动update。那么Hibernate如何判断究竟对child是save还是update呢?它会取一下child的主键属性 child.getId() ,这里假设id是 java.lang.Integer类型的。如果取到的Id值和hbm映射文件中指定的unsave-value相等,那么Hibernate认为child是新的内存临时对象,发送save,如果不相等,那么Hibernate认为child是已经持久过的对象,发送update。

unsaved-value="null" (默认情况,适用于大多数对象类型主键 Integer/Long/String/...)

当Hibernate取一下child的Id,取出来的是null(在上例中肯定取出来的是null),和unsaved-value设定值相等,发送save(child)

当Hibernate取一下child的id,取出来的不是null,那么和unsaved-value设定值不相等,发送update(child)

例如下面的情况:

 1Session session = ;   
 2Transaction tx = ;   
 3  
 4Parent parent = (Parent) session.load(Parent.class, id);   
 5Child child = (Child) session.load(Child.class, childId);   
 6  
 7child.setParent(parent);   
 8child.setName("sun");   
 9  
10parent.addChild(child);   
11s.update(parent);   
12  
13s.flush();   
14tx.commit();   
15s.close();  

child已经在数据库中有了,是一个持久化的对象,不是新创建的,因此我们希望Hibernate发送update(child),在该例中,Hibernate取一下child.getId(),和unsave-value指定的null比对一下,发现不相等,那么发送update(child)。

parent对象不需要操心,因为程序显式的对parent有load操作和update的操作,不需要Hibernate自己来判断究竟是save还是update了。我们要注意的只是child对象的操作。另外unsaved-value是定义在Child类的主键属性中的。


 
1<class name="Child" table="child">  
2<id column="id" name="id" type="integer" unsaved-value="null">  
3  <generator class="identity"/>  
4</id>  
5   
6</class>  
7

如果主键属性不是对象型,而是基本类型,如int/long/double/...,那么你需要指定一个数值型的unsaved-value,例如:
1unsaved-value="0"

很多人以为对主键属性定义为int/long,比定义为Integer/Long运行效率来得高,认为基本类型不需要进行对象的封装和解构操作,因此喜欢把主键定义为int/long的。但实际上,Hibernate内部总是把主键转换为对象型进行操作的,就算你定义为int/long型的,Hibernate内部也要进行一次对象构造操作,返回给你的时候,还要进行解构操作,效率可能反而低也说不定。因此大家一定要扭转一个观点,在Hibernate中,主键属性定义为基本类型,并不能够比定义为对象型效率来的高,而且也多了很多麻烦,因此建议大家使用对象型的Integer/Long定义主键.

摘自javaeye
posted on 2007-06-04 09:44 扭曲的铅笔 阅读(704) 评论(0)  编辑  收藏 所属分类: Hibernate

只有注册用户登录后才能发表评论。


网站导航: