﻿<?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-一只灰机-随笔分类-Hibernate</title><link>http://www.blogjava.net/noaso/category/47071.html</link><description>蓝色</description><language>zh-cn</language><lastBuildDate>Wed, 17 Nov 2010 05:35:57 GMT</lastBuildDate><pubDate>Wed, 17 Nov 2010 05:35:57 GMT</pubDate><ttl>60</ttl><item><title>Hibernate中cascade与inverse属性详解</title><link>http://www.blogjava.net/noaso/archive/2010/11/17/338247.html</link><dc:creator>noaso</dc:creator><author>noaso</author><pubDate>Wed, 17 Nov 2010 05:31:00 GMT</pubDate><guid>http://www.blogjava.net/noaso/archive/2010/11/17/338247.html</guid><wfw:comment>http://www.blogjava.net/noaso/comments/338247.html</wfw:comment><comments>http://www.blogjava.net/noaso/archive/2010/11/17/338247.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/noaso/comments/commentRss/338247.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/noaso/services/trackbacks/338247.html</trackback:ping><description><![CDATA[<div class="postText">
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">关于Hibernate中 cascade 与
inverse 的理解。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">您买的Hibernate书是哪一本呢？
孙卫琴的精通Hibernate，还是
深入浅出Hibernate还是那本。。。<br />
我是两本都买了，总体来说还可以，但是，有的地方讲的比较书面化，比如inverse这属性。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">在学习Hibernate的过程中最不好理解的就是这两个属性了。<br />
(我当初学习Hibernate的时候，发现网上介绍这两个属性的文章倒是不少，但是，居然有好多都是转帖。。。还有的就是
照书搬~~-_-!!!)。。。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">据个例子：书上说inverse=false时，由主控方维持关系。。。<br />
由于我也是初学者。。。再加上语文水平偏低。。。不理解&#8220;维持关系是啥意思&#8221;囧~</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">提示：<br />
(1)如果：您不了解Hibernate的one-to-many或many-to-one的概念。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">(2)如果：你不了解Hibernate的&#8220;自由态&#8221;&#8220;持久态&#8221;&#8220;游离态&#8221;的概念。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">(3)如果：您不了解Hibernate中的&#8220;脏数据&#8221;的概念。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">(4)如果：您对Hibernate中Session缓存，没有初步了解的话。<br />
(在Hibernate中调用save进行存储数据的时候,并不是马上就对数据库进行insert操作，而是会将其&#8220;数据对象(vo)&#8221;纳入Hibernate的Session缓存。)</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">在上面的4条提示中，如果您对其中的某一条，不是很清楚的话。希望请先了解有关知识。<br />
否则，可能您将
&#8220;无法或很难&#8221;理解 cascade 或 inverse 这2个属性。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">首相，cascade 与 inverse
这两个属性，其实是完全不同的两个东西，想要了解他们各自的&#8220;用途与区别&#8221;，详见如下介绍：</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">这里有两个表:</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">（1）class&nbsp;&nbsp;
(班级表)<br />
相应字段：<br />
cid&nbsp;&nbsp;&nbsp; varchar(32) 主键 not-null (班级id)<br />
cname
varchar(16)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; not-null (班级名称)&nbsp;&nbsp; <br />
<br />
（2）student (学生表)<br />
相应字段：<br />
sid&nbsp;&nbsp;&nbsp;
varchar(32) 主键 not-null (学生id)<br />
sname varchar(16)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; not-null
(学生姓名)<br />
class_id varchar(32)&nbsp;&nbsp; not-null
(学生所属班级)</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">一个班级(class)对应多个学生(student)，所以班级表(class)就是&#8220;one-to-many&#8221;端<br />
反之student就是many-to-one</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">//--------Class类的代码--------<br />
public class Class
implements.....<br />
{<br />
private cId = "";<br />
private cName = "";<br />
private
students = java.util.HashMap();<br />
// 省略对应的 geter
setter<br />
}<br />
//--------Class.hbm.xml--------<br />
&lt;hibernate-mapping&gt;<br />
&lt;class
name="lcx.vo.Class" table="class"<br />
&nbsp;&nbsp; catalog="demo"&gt;<br />
&nbsp;&nbsp; &lt;id
name="cid" type="java.lang.String"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;column name="cid" length="32"
/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;generator class="uuid.hex" /&gt;<br />
&nbsp;&nbsp; &lt;/id&gt;<br />
&nbsp;&nbsp;
&lt;property name="name" type="java.lang.String"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;column
name="cname" length="16" not-null="true" /&gt;<br />
&nbsp;&nbsp;
&lt;/property&gt;<br />
&nbsp;&nbsp;<br />
&nbsp;&nbsp; &lt;set name="students" table="student"
cascade="save-update"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;key column="class" /&gt;<br />
&nbsp;&nbsp;&nbsp;
&lt;one-to-many class="lcx.vo.Student" /&gt;<br />
&nbsp;&nbsp; &lt;/set&gt;
<br />
&lt;/class&gt;<br />
&lt;/hibernate-mapping&gt;</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">//--------Student类的代码;*******<br />
public class Student
implements.....<br />
{<br />
private sId = "";<br />
private sName = "";<br />
private
Class class = null;<br />
// 省略对应的 geter setter<br />
}<br />
//
Student.hbm.xml<br />
&lt;hibernate-mapping&gt;<br />
&lt;class name="lcx.vo.Student"
table="student" catalog="demo"&gt;<br />
&nbsp;&nbsp; &lt;id name="cid"
type="java.lang.String"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;column name="sid" length="32"
/&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;generator class="uuid.hex" /&gt;<br />
&nbsp;&nbsp; &lt;/id&gt;<br />
&nbsp;&nbsp;
&lt;many-to-one name="class" <br />
&nbsp;&nbsp;&nbsp; class="lcx.vo.Class"<br />
&nbsp;&nbsp;&nbsp;
column="class_id" <br />
&nbsp;&nbsp;&nbsp; not-null="true" <br />
&nbsp;&nbsp;
/&gt;&nbsp;&nbsp;&nbsp;<br />
&lt;/class&gt;<br />
&lt;/hibernate-mapping&gt;</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">（一） cascade
的介绍：<br />
当Hibernate持久化一个&#8220;临时对象(也叫自由态对象)&#8221;时，在默认的情况下(即：没有设置cascade属性或cascade=none时)，Hibernate不会自动&#8220;持久化他所关联&#8221;的其他临时对象。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">上面这些话是什么意思呢？ 什么叫不会自动
&#8220;持久化&#8221;关联的临时对象呢？</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">看如下代码：</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">// 创建一个 临时对象(也叫自由态对象)
<br />
// 也就是说这个 class 没有被Hibernate纳入Session缓存管理。<br />
Class class = new
Class();<br />
//class.id
为自动生成<br />
class.setName("一年级1班");</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">Student stu = new
Student();<br />
//student.id
为自动生成<br />
stu.setName("小白兔");<br />
stu.setClass(class);</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">//
关键就是这里。。。<br />
class.getStudents().add(stu);</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">session.save(class);<br />
//
提交</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">// 注意:
Class.hbm.xml文件中,cascade="save-update"并且也没有设置inverse属性,也就是说inverse=false;<br />
//
此时如果你开启了Hibernate的显示HQL语句功能，那么控制台将会显示如下3条HQL：</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">//----------------------------------------********<br />
insert
into demo.class (cid, cname) values (66666666666666666666666666666666,
一年级1班)<br />
insert into demo.student (sid,sname,class_id) values
(8888888888888888811cb2e04c888888, 小白兔,
66666666666666666666666666666666)<br />
update demo.student set
class_id=66666666666666666666666666666666 where
sid=8888888888888888811cb2e04c888888<br />
//----------------------------------------********</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">那么为什么会出现，这3条HQL语句呢，我们来一一分析一下：</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">第1条HQL语句:<br />
其实第一条HQL比较好理解，<br />
当我们调用 session.save(class)
后，在Hibernate进行提交的时候，<br />
会发现&#8220;有&#8221;一条&#8220;新&#8221;的数据要插入(insert)，所以就往class表中,插入了这条新的class记录。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">第2条HQL语句：<br />
注意问题就在这里：<br />
这里为什么又出现了一条insert语句呢？而且还是向student表中插入数据。<br />
我们在上面的代码中，并没有编写类似&#8220;session.save(student)&#8221;这样的语句啊。<br />
这是为什么呢？<br />
其实原因，是这么回事：因为我们在class端，设置了"级联更新"(即:cascade="save-update")，<br />
也就是说，当Hibernate在向class表中插入&#8220;新&#8221;对象记录时，会检查&#8220;Class对象&#8221;所关联的属性(就是&lt;set&gt;对应的属性)，是否发生过变化，如果发生了变化，就按照&#8220;级联属性(cascade)&#8221;所设定的内容<br />
进行操作。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">上面讲的这句话到底是什么意思呢？<br />
用你们&#8220;人&#8221;话说，就是：<br />
因为调用了
class.getStudents().add(stu);<br />
所以，在Hibernate在进行插入
class对象的时候，发现class对象，所关联的集合中，有一条<br />
&#8220;自由态&#8221;的对象，而又因为class端设置了&#8220;级联属性cascade&#8221;，所以，在插入这条
&#8220;新class对象&#8221;时，也一同把他内部的那些，还属于&#8220;自由态&#8221;的其他对象，也一同插入到，他们所对应的表中去了。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">还是不明白的话。。。可以看看。孙卫琴的《精通Hibernate》，在书上的第149页有。<br />
但是关于inverse的介绍。。。写的就有些书面化了，如果语文不好的话。。。就难懂咯~</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">第3条HQL语句：<br />
第三条HQL语句是一条update语句，是不是觉得，很莫名其妙。。。。<br />
Hibernate大脑进水了吧，怎么吃饱了撑得，重复更新记录啊啊啊啊啊<br />
假如：我们把
class端的配置文档中的
invser属性设置为true(即：inverse=true)<br />
在执行上面的程序，发现，就变成2条insert语句啦。。。。。(update没啦。。。)<br />
看来第三条的update语句和inverse有着密切的关系（他两有一腿~）。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">所以我们下边，就来介绍一下inverse属性:</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">当调用
Class.getStudents().add(stu)方法，进行添加操作时， <br />
(即：向 "这个Class对象"所属的&#8220;集合
(也就是调用getStudents方法所返回的那个Set集合)&#8221;中添加一个Student(即
add(stu))，也就是说，这个&#8220;新&#8221;添加的Student对象(stu)，
<br />
他的Student.class_id字段&#8220;必须&#8221;，要等于&#8220;被添加方Class&#8221;的主键(即:Class.cid)。
<br />
从&#8220;数据库&#8221;层面来讲，也就是说，这个&#8220;新&#8221;添加的&#8220;Student&#8221;的class_id字段，必须要与&#8220;Class&#8221;的cid字段，存在"主外键关联"。)
</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">正因为如此：所以Hibernate&#8220;怕&#8221; 在进行
"Class.getStudents().add(stu)" 这样的操作时， <br />
出现意外情况(如:
stu.getClass=null，即：stu没有所属班级)，<br />
即&#8220;添加方&#8221;(Student)与&#8220;被添加方&#8221;(Class)，存在&#8220;外键&#8221;不一致的情况发生。
<br />
所以就出现了 那条多余的update语句。即：one-to-many（Class端）主动去维护Child.Class_id
<br />
所以就是说，Hibernate怕出错，就给你多执行一次无用的更新语句，以保证 add 到
Class&#8220;集合&#8221;中的所有Student<br />
都是要与Class有外键关联的。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">用普通话说就是:<br />
一年1班.getStudents().add(小白兔);<br />
一年1班.getStudents().add(大白兔);</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">也就是说现在不管是 小白兔 还是 大白兔
<br />
如果他们，目前还没有自己的班级的话，<br />
一年1班的班主任就会主动邀请他们成为一年1班的同学啦~。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">也就是说 一年1班的班主任 主动邀请 同学，而不是
同学自己来~~~ 所以效率也降低了。。。。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">所以我们一般把 一对多端
invser设置为true，即：不让主控端去维护主键关联，<br />
（即：让同学自己去找班级）<br />
说白了，就是，one-to-many端不用去管理
&#8220;新添加对象&#8221; 的主外键约束问题。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">把one-to-many端（即:class端)的invser设置为true<br />
(即：每次向class.getStudents这个集合中添加
student时，不去主动update对应的外键)，<br />
而是在student端去手动设置<br />
例如：<br />
student.setClass(class);<br />
session.save(student);<br />
这样手动设置
student与class关联啦。。。。<br />
所以上面的程序&#8220;最好&#8221;还是写成这样：</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">Class class = new
Class();<br />
class.setName("一年级1班");<br />
session.save(class);</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">Student stu = new
Student();<br />
stu.setName("小白兔");<br />
stu.setClass(class);<br />
session.save(class);</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">/*<br />
此时向class集合add内容，不会进行数据库操作(update)。<br />
&#8220;更新&#8221;的只是session缓存中，数据镜像。<br />
这样做的好处是：不仅减少了update语句，<br />
而且，同时也更新了session缓存。<br />
------------------------<br />
而在原来:<br />
one-to-many端inverse=false时，虽然也更新seesion缓存中的class集合，<br />
但是有却又多余update<br />
*/<br />
class.getStudents().add(stu);<br />
//
提交</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">总结:<br />
当inverse=false
并且向one-to-many端的关联集合，添加&#8220;新对象(即: 自由态对象)&#8221; 时，<br />
Hibernate就会自动，去update那&#8220;个刚刚到来的&#8221;
&#8220;自由态对象&#8221;的外键。<br />
（如果你向，one-to-many端添的集合中，add一个&#8220;已经持久化了的对象&#8221;，那就不会出现update了(因为已经持久化过了)，除非，你去
更改&#8220;那个持久化对象&#8221;所对应的外键。。。那样的话。。。呵呵呵~~~<br />
你可以试一试，应该不会报错，你可以当做练习去做一下，加深cascade和inverse这两个属性的理解）</span></span></span></span></span></span></p>
<p><br />
<span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">//
如果看懂了上面的内容。来看一下，下面的东西。<br />
假如，将one-to-many端(即:Class端)的 hbm.xml 文档中的cascade移除掉
或把cascade="none"。<br />
那么上面的代码会出现什么情况呢。<br />
结果会出现2条HQL，和一堆Exception</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">insert into demo.class
(cid, cname) values (66666666666666666666666666666666, 一年级1班)<br />
update
demo.student set class_id=66666666666666666666666666666666 where
sid=8888888888888888811cb2e04c888888<br />
Hibernate
Exceptinon......................................
</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">相比较cascade被设置"save-update"的时候，缺少了1条
insert语句，而且也多了一些Exception。</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">那么，到底是少了哪1条insert语句呢？<br />
就是这条：<br />
insert into
demo.student (sid,sname,class_id) values (8888888888888888811cb2e04c888888, 小白兔,
66666666666666666666666666666666)</span></span></span></span></span></span></p>
<p><span style="font-size: 14pt;"><span style="font-size: 14pt;"><span style="font-size: 10pt;"><span style="font-size: 12pt;"><span style="font-size: 12pt;"><span style="font-size: 10pt;">之所以会出现，这样的现象，想必您已经早就看出来了。<br />
因为，我没有设置Class端的Cascade，所以在save(class)的时候，并没有自动将其所关联的&#8220;自由态对象&#8221;进行持久化操作。<br />
然而，又因为
Class端的inverse=false，所以，Class会自动去维持，那个 &#8220;新来的student&#8221;
的外键。<br />
所以会出现，没有insert就要update啦。。。。<br />
然后在就是Exception了</span></span></span></span></span></span></p>
</div>
<img src ="http://www.blogjava.net/noaso/aggbug/338247.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/noaso/" target="_blank">noaso</a> 2010-11-17 13:31 <a href="http://www.blogjava.net/noaso/archive/2010/11/17/338247.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>