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