﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-大家一起忙~~-随笔分类-j2ee</title><link>http://www.blogjava.net/zhangyy130/category/38678.html</link><description>勤工好学！地方门户的目标不能变！！</description><language>zh-cn</language><lastBuildDate>Mon, 30 Mar 2009 10:01:56 GMT</lastBuildDate><pubDate>Mon, 30 Mar 2009 10:01:56 GMT</pubDate><ttl>60</ttl><item><title>inverse 与 cascade 的区别</title><link>http://www.blogjava.net/zhangyy130/archive/2009/03/30/262921.html</link><dc:creator>张永耀</dc:creator><author>张永耀</author><pubDate>Mon, 30 Mar 2009 08:46:00 GMT</pubDate><guid>http://www.blogjava.net/zhangyy130/archive/2009/03/30/262921.html</guid><wfw:comment>http://www.blogjava.net/zhangyy130/comments/262921.html</wfw:comment><comments>http://www.blogjava.net/zhangyy130/archive/2009/03/30/262921.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangyy130/comments/commentRss/262921.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangyy130/services/trackbacks/262921.html</trackback:ping><description><![CDATA[<table style="table-layout: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt" id="blog_text">
            <p><font color="#ff0000">1.作用的范围不同：</font></p>
            <p>1）inverse ：&lt;set/&gt;,&lt;map/&gt;,&lt;list/&gt;,&lt;array/&gt;,&lt;bag/&gt;</p>
            <p>2）cascade ：&lt;many-to-one&gt;,&lt;one-to-one/&gt;,&lt;set/&gt;,&lt;map/&gt;,&lt;list/&gt;,&lt;array/&gt;,&lt;bag/&gt;.</p>
            <p><font color="#ff0000">2.执行策略不同</font></p>
            <p>1）inverse ：首先判断集合的变化情况，然后针对变化执行相应的处理。</p>
            <p>2）cascade ：直接对集合中的每个元素执行相应的处理。</p>
            <p><font color="#ff0000">3.执行的时机不同</font></p>
            <p>1）inverse ：在执行SQL语句之前判断是否要执行该SQL语句。</p>
            <p>2）cascade ：在主控方发生操作时用来判断是否进行级联操作。</p>
            <p><font color="#ff0000">4.执行的目标不同</font></p>
            <p>1）inverse ：对于&lt;one-to-many&gt;处理被管理表，&lt;many-to-many/&gt;处理中间表。</p>
            <p>2）cascade ：都只只对被关联表。</p>
            <p>总结：书上说了inverse 一对多的时候最好把多的一方设置成false由一的一方来控制；cascade尽量别使，进行显示的添加删除。</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
 <img src ="http://www.blogjava.net/zhangyy130/aggbug/262921.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangyy130/" target="_blank">张永耀</a> 2009-03-30 16:46 <a href="http://www.blogjava.net/zhangyy130/archive/2009/03/30/262921.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(zt) 高级配置及机制 hibernate</title><link>http://www.blogjava.net/zhangyy130/archive/2009/03/30/262904.html</link><dc:creator>张永耀</dc:creator><author>张永耀</author><pubDate>Mon, 30 Mar 2009 08:06:00 GMT</pubDate><guid>http://www.blogjava.net/zhangyy130/archive/2009/03/30/262904.html</guid><wfw:comment>http://www.blogjava.net/zhangyy130/comments/262904.html</wfw:comment><comments>http://www.blogjava.net/zhangyy130/archive/2009/03/30/262904.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangyy130/comments/commentRss/262904.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangyy130/services/trackbacks/262904.html</trackback:ping><description><![CDATA[<p>构造这样一个例子，在测试过程中来说明一些Hibernate的高级配置及其相关机制：<br />
有三个类：Category.java,Prodcuct.java,ConfigurationTest.java，其中第三个类是用来测试的。<br />
Category.java代码： <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>package unsaved_value;&nbsp;&nbsp;&nbsp;&nbsp; <br />
import ......&nbsp;&nbsp;&nbsp;&nbsp; <br />
public class Category {&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private Integer id;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private String name;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private String description;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private Set products;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Category(){&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id=null;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name=null;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; description=null;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; products=new HashSet ();&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; public void addProduct(Product p){&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; products.add(p);&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; //**********setter and getter&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; ........&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;</p>
<p><br />
Product.java代码：</p>
<p><br />
package unsaved_value;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
public class Product {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private Integer id;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private String name;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private Category category;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; private String description;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public Product(){&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; //*******getter and setter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; .........&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
ConfigurationTest.java<br />
<br />
public void testSave()throws Exception{&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Category category=new Category();&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; category.setName("java编程书籍2");&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; category.setDescription("编程经典书籍2");&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Product pro=new Product();&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pro.setName("java编程思想2");&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pro.setDescription("第四版中文版2");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pro.setCategory(category);&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; category.addProduct(pro);&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Transaction tx=session.beginTransaction();&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assert (session!=null):("session is null");&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; session.save(category);&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tx.commit();&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
Category代表产品目录，而Product代表产品，显然Category与Product是一对多的关系。Hibernate在映射一对多关系时，有两种方式，一种是单向一对多，一种是双向关系。两者相比，双向一对多的好处体现在两方面：首先，也是很明显的一点，由于是双向关联，我们在实际业务逻辑时将更方便，例如我们可以检索一个Category下的所有Product，同时还可以检索出Product属于哪个。其次，双向关系相对单向关系而言，在数据库的访问方面更有优势。这一点留在后面讲inverse时讲<br />
。双向关联比单向关联唯一的&#8221;劣势&#8220;，就在于双向关联需要比单向关联多写一个映射文件，这不问题。使用双向关联实现这两个类同数据库的映射： <br />
<br />
Category.hbm.xml:&nbsp;&nbsp; <br />
version="1.0" encoding="UTF-8"?&gt;&nbsp;&nbsp;</p>
<p>"<a href="http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd</a>" &gt;&nbsp;&nbsp; <br />
&lt;hibernate-mapping package="unsaved_value"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp; &lt;class name="Category" table="category"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;id name="id" column="id"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;generator class="native"&gt;generator&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; id&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="name" column="name"/&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="description" column="description"/&gt;</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;set name="products" table="product" lazy="true" inverse="true" cascade="all"&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;key column="category"/&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;one-to-many class="Product"/&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; set&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp; class&gt;&nbsp;&nbsp; <br />
hibernate-mapping&gt;&nbsp;&nbsp; <br />
&nbsp;&nbsp; <br />
Product.hbm.xml:</p>
<p><br />
version="1.0" encoding="UTF-8"?&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
"<a href="http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd</a>" &gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&lt;hibernate-mapping package="unsaved_value"&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&lt;class name="Product" table="product"&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;id name="id" column="id" unsaved-value="null"&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;generator class="native"&gt;generator&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; id&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="name" column="name"/&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="description" column="description"/&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; &lt;many-to-one name="category"&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; column="category"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class="Category"&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; /&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp; class&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
hibernate-mapping&gt;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
现在把这个例子所牵涉到的知识一一展开：<br />
一.inverse<br />
&nbsp;&nbsp;&nbsp; 该词的译意是&#8220;反转&#8221;,反转什么——反转控制端，这项配置决定了由关联双方中的哪一方来维持关联关系（在数据库中表现为外键约束）。上述配置中，在Category.hbm.xml中将inverse设置为true,意思是说&#8220;我需要反转（控制端）&#8221;，反转的结果是由对方即Product来维持关联关系。用单向关联更容易说明&#8221;维持关联关系&#8220;是什么意思：考虑用单向关系来实现这个映射关系的情况，即由Category关联到Product，考虑下面的代码： <br />
<br />
Product p=new Product();&nbsp;&nbsp; <br />
..setXXX&nbsp;&nbsp; <br />
Category c=new Category();&nbsp;&nbsp; <br />
..设置Category的属性&nbsp;&nbsp; <br />
c.addProduct(p);//建立起了c和p的关联关系&nbsp;&nbsp; <br />
session.save(c);&nbsp;&nbsp;</p>
<p>会执行三条SQL语句:两条插入语句，分别插入c和p，然后还有一条update语句建立起c和p的关联（更新p的外键）。上面，我们说由Category端控制关联，因此p.setCategory(c)这样一句话是没用的,它并不会导致在插入p的时候就设置p的外键以建立起两者的关联关系，从而节省一条update语句。同时我们还会看到，如果在数据库模式中将p的外键设置成非空，这些代码将不能执行，因为在插入p时，由于c和p的关联关系还未建立起来，因此p的外键为空。回到双向关联上来，为了更清楚地明白inverse在双向关联中到底起什么作用，我们分别将其值设为true和false,看看打印出的的SQL有何区别：</p>
<p>inverse=true时的打印结果：<br />
<br />
Hibernate: insert into category (name, description) values (?, ?)&nbsp;&nbsp; <br />
Hibernate: insert into product (name, description, category) values (?, ?, ?)&nbsp;&nbsp;&nbsp; <br />
inverse=false时的打印结果：<br />
<br />
Hibernate: insert into category (name, description) values (?, ?)&nbsp;&nbsp;&nbsp;&nbsp; <br />
Hibernate: insert into product (name, description, category) values (?, ?, ?)&nbsp;&nbsp;&nbsp;&nbsp; <br />
Hibernate: update product set category=? where id=?&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为什么inverse=true时会比inverse=false时少执行一条SQL语句？这是由控制端的不同造成的。前者说"我要反转控制，由Product来控制关联"，因此在将p对象insert时，p已经设置了其category字段，从而建立了关联关系，而后者说"我不反转控制，由我自己来控制关联",因此在将p对象insert后，c为了维持两者的关联，还要去执行一次update，以更新p的外键，从而建立起两者的关联关系。<br />
结论：对于一对多双向关系，始终在&#8220;一&#8221;那一方将其inverse设置成true,这样会提高性能。</p>
<p>二.cascade<br />
&nbsp;&nbsp; 级联。当关联的"一"方进行某种动作（更新，删除）时，"多"方即使没有显式地进行编码，它也会自动进行同样的动作。cascade的可选值有：<br />
all : 所有情况下均进行关联操作。即是save-update + delete<br />
none：所有情况下均不进行关联操作。这是默认值。<br />
save-update:在执行save/update/saveOrUpdate时进行关联操作。<br />
delete：在执行delete时进行关联操作。<br />
all-delete-orphan:A:级联save-update B级联delete C:删除所有孤儿项（orphan孤儿）。先看看父子关系，例如在Customer和Order的模型中，这两者便是父子关系，当一个Customer的生命周期决定Order的生命周期，如果一个Customer不在了，其相关的Order继续存在是毫无业务意义的。删除所有孤儿项的意思即是，删除所有与父对象失去关联关系的子对象。</p>
<p>三.lazy<br />
&nbsp;&nbsp;&nbsp; 是否延迟加载。一般来说，应该延迟加载，即将lazy设为true。延迟加载的相关点很多，这在另外的学习笔记中总结。</p>
<p>四.unsaved-value<br />
&nbsp;&nbsp;&nbsp; 以上是"一"方的重要配置，再看看"多"方的一个重要配置:unsaved-value,就像上面Product.hbm.xml中的设置那样，这一项在id的配置中设置。这一设置是与级联一起工作的。关于这一点，robbin讲的很清楚：<br />
当你显式的使用session.save()或者session.update()操作一个对象的时候，实际上是用不到unsaved-value 的。某些情况下(父子表关联保存)，当你在程序中并没有显式的使用save或者update一个持久对象，那么Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象，是一个尚未被持久化过的内存临时对象。例如： <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Session session = ...; <br />
Transaction tx = ...;&nbsp;&nbsp; <br />
Parent parent = (Parent) session.load(Parent.class, id);&nbsp;&nbsp; <br />
Child child = new Child();&nbsp;&nbsp; <br />
child.setParent(parent);&nbsp;&nbsp; <br />
child.setName("sun");&nbsp;&nbsp; <br />
parent.addChild(child);&nbsp;&nbsp; <br />
s.update(parent);&nbsp;&nbsp; <br />
s.flush();&nbsp;&nbsp; <br />
tx.commit();&nbsp;&nbsp; <br />
s.close();&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; 在上例中，程序并没有显式的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/...)<br />
当Hibernate取一下child的Id，取出来的是null(在上例中肯定取出来的是null)，和unsaved-value设定值相等，发送save(child)<br />
当Hibernate取一下child的id，取出来的不是null，那么和unsaved-value设定值不相等，发送update(child)<br />
&nbsp;&nbsp; unsaved-value的可选配置有：<br />
none，any，null<br />
unsaved-value="none"和unsaved-value="any"主要用在主键属性不是通过Hibernate生成，而是程序自己setId()的时候。unsaved-value="none"和unsaved-value="any"究竟有什么含义了。如果你非要用assigned不可，那么继续解释一下：<br />
unsaved-value="none" 的时候，由于不论主键属性为任何值，都不可能为none，因此Hibernate总是对child对象发送update(child)<br />
unsaved-value="any" 的时候，由于不论主键属性为任何值，都肯定为any，因此Hibernate总是对child对象发送save(child)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 大多数情况下，可以避免使用assigned，只有当你使用复合主键的时候不得不手工setId()，这时候需要你自己考虑究竟怎么设置unsaved-value了，根据你自己的需要来定。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关于为什么不要使主键带有义务意义，robbin的解释很清楚：还是以上面的例子打比方，如果我们将Category的某一个性质（比如产品序号或者名称）作为主键，如果后来由于业务需要，我们把这个性质改了，那将不可僻免地要去修改与这个对象相关联的所有数据的外键，而如果我们只要代理主键，这个问题就可完全僻免。</p>
 <img src ="http://www.blogjava.net/zhangyy130/aggbug/262904.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangyy130/" target="_blank">张永耀</a> 2009-03-30 16:06 <a href="http://www.blogjava.net/zhangyy130/archive/2009/03/30/262904.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ResultSet can not re-read row data for column 问题</title><link>http://www.blogjava.net/zhangyy130/archive/2009/03/27/262415.html</link><dc:creator>张永耀</dc:creator><author>张永耀</author><pubDate>Fri, 27 Mar 2009 06:25:00 GMT</pubDate><guid>http://www.blogjava.net/zhangyy130/archive/2009/03/27/262415.html</guid><wfw:comment>http://www.blogjava.net/zhangyy130/comments/262415.html</wfw:comment><comments>http://www.blogjava.net/zhangyy130/archive/2009/03/27/262415.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangyy130/comments/commentRss/262415.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangyy130/services/trackbacks/262415.html</trackback:ping><description><![CDATA[今天在写程序的时候发现了一个很奇怪的问题&#8220;ResultSet can not re-read row data for column&#8221;，用google一搜，原来是微软公司的驱动的兼容性不太好。有热心人总结了微软驱动的缺点：（1）如果采用jdbc-odbc驱动，那么就必须按照查询顺序来一次读取（不论有没有image或text,ntext类型）（2）如果采用微软提供的ms sql server jdbc driver，如果查询语句中，不存在image或text,ntext类型字段，那么可以按照无序获取（3）如果采用微软提供的ms sql server jdbc driver，如果查询语句中，存在image或text,ntext类型字段，那么就必须按照顺序读取，否则就会报告Driver]ResultSet can not re-read row data for column之类的错误（4）如果想不查询语句中有没有image或text,,ntext类型字段，都可以不按照顺序获取，或重复获取。那么就必须更换驱动，改用第三方的。　最后，我改用了第三方的驱动。测试成功。
 <img src ="http://www.blogjava.net/zhangyy130/aggbug/262415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangyy130/" target="_blank">张永耀</a> 2009-03-27 14:25 <a href="http://www.blogjava.net/zhangyy130/archive/2009/03/27/262415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>