﻿<?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学习笔记-随笔分类-hibernate</title><link>http://www.blogjava.net/migrant/category/41324.html</link><description>我们的失落……</description><language>zh-cn</language><lastBuildDate>Thu, 27 Aug 2009 21:42:23 GMT</lastBuildDate><pubDate>Thu, 27 Aug 2009 21:42:23 GMT</pubDate><ttl>60</ttl><item><title>[转]Hibernate saveorUpdate与unsaved-value，save，update，delete总结</title><link>http://www.blogjava.net/migrant/archive/2009/08/27/292815.html</link><dc:creator>J2EE学习笔记</dc:creator><author>J2EE学习笔记</author><pubDate>Thu, 27 Aug 2009 06:44:00 GMT</pubDate><guid>http://www.blogjava.net/migrant/archive/2009/08/27/292815.html</guid><wfw:comment>http://www.blogjava.net/migrant/comments/292815.html</wfw:comment><comments>http://www.blogjava.net/migrant/archive/2009/08/27/292815.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/migrant/comments/commentRss/292815.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/migrant/services/trackbacks/292815.html</trackback:ping><description><![CDATA[<p><span style="font-family: 新宋体"><span style="font-size: 10pt">这些操作对经常使用hibernate的同学已经很熟悉了，我也经常用但一些细节并不了解， <br />
最近遇到问题才开始有看了一下。</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">在读完robbin的这两个精华贴的时候，感觉清晰了很多，确实好文章。 <br />
</span></span><a href="http://www.javaeye.com/topic/2712" target="blank"><span style="font-family: 新宋体"><span style="font-size: 10pt">http://www.javaeye.com/topic/2712</span></span></a><span style="font-family: 新宋体"><span style="font-size: 10pt"> <br />
</span></span><a href="http://www.javaeye.com/topic/1604?page=1" target="blank"><span style="font-family: 新宋体"><span style="font-size: 10pt">http://www.javaeye.com/topic/1604?page=1</span></span></a><span style="font-family: 新宋体"><span style="font-size: 10pt"> <br />
还有这个精华贴 <br />
</span></span><a href="http://www.javaeye.com/topic/7484" target="blank"><span style="font-family: 新宋体"><span style="font-size: 10pt">http://www.javaeye.com/topic/7484</span></span></a><span style="font-family: 新宋体"><span style="font-size: 10pt"> <br />
也很不错。</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">里面总结的很好了，我结合以上三个帖子、自己的试验（版本hibernate-3.0.5）和Hibernate文档也总结了一点，加深理解。<strong><span style="color: red">希望对刚开始学Hibernate的同学有所帮助</span>。</strong></span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt"><span style="color: red">一、saveorUpdate与unsaved-value</span> <br />
到底是sava还是update <br />
Hibernate需要判断被操作的对象究竟是一个已经持久化过的持久对象还是临时对象。 <br />
<strong>1）．主键Hibernate的id generator产生</strong> <br />
&lt;id name="id" type="java.lang.Long"&gt; <br />
&lt;column name="ID" precision="22" scale="0" /&gt; <br />
&lt;generator class="increment" /&gt; <br />
&lt;/id&gt;</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">Project project = new Project(); <br />
project.setId(XXX); <br />
this.projectDao.saveOrUpdate(project);</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">1、默认unsaved-value="null" <br />
<strong>主键是对象类型，hebernate判断project的主键是否位null，来判断project是否已被持久化</strong> <br />
是的话，对project对象发送save(project)， <br />
若自己设置了主键则直接生成update的sql，发送update(project)，即便数据库里没有那条记录。 <br />
主键是基本类型如int/long/double/ <br />
自己设置unsaved-null="0"。 <br />
所以这样的话save和update操作肯定不会报错。</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">2、unsaved-value="none"， <br />
由于不论主键属性为任何值，都不可能为none，因此Hibernate总是对project对象发送update(project)</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">3、unsaved-value="any" <br />
由于不论主键属性为任何值，都肯定为any，因此Hibernate总是对project对象发送save(project)，hibernate生成主键。</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">Hibernate文档中写到 <br />
saveOrUpdate()完成了如下工作： <br />
如果对象已经在这个session中持久化过了，什么都不用做 <br />
如果对象没有标识值，调用save()来保存它 <br />
如果对象的标识值与unsaved-value中的条件匹配，调用save()来保存它 <br />
如果对象使用了版本(version或timestamp),那么除非设置unsaved-value="undefined",版本检查会发生在标识符检查之前. <br />
如果这个session中有另外一个对象具有同样的标识符，抛出一个异常 </span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt"><strong>2）．主键由自己来赋值</strong> <br />
&lt;id name="id" type="java.lang.Long"&gt; <br />
&lt;column name="ID" precision="22" scale="0" /&gt; <br />
&lt;generator class="assigned" /&gt; <br />
&lt;/id&gt;</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">Project project = new Project(); <br />
project.setId(XXX); <br />
this.projectDao.saveOrUpdate(project);</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">1、默认unsaved-value="null" <br />
<strong>这时有所不同，hibernate会根据主键产生一个select，来判断此对象是否已被持久化</strong> <br />
已被持久化则update，未被持久化则save。 <br />
2、unsaved-value="none"，update对象，同上</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">3、unsaved-value="any" ，save对象， <br />
如果自己自己设置的ID在数据库中已存在，则报错。</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt"><span style="color: red">二、save与update操作</span> <br />
显式的使用session.save()或者session.update()操作一个对象的时候，实际上是用不到unsaved-value的 <br />
在同一Session，save没什么可说得 <br />
update对象时, 最直接的更改一个对象的方法就是load()它，保持Session打开，然后直接修改即可: <br />
Session s =&#8230; <br />
Project p = (Project) sess.load(Project.class, id) ); <br />
p.setName(&#8220;test&#8221;); <br />
s.flush(); <br />
不用调用s.update(p);hibernate能察觉到它的变化，会自动更新。当然显示调用的话也不会错</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">Hibernate文档中写到 <br />
update()方法在下列情形下使用： <br />
程序在前面的session中装载了对象 <br />
对象被传递到UI（界面）层 <br />
对该对象进行了一些修改 <br />
对象被传递回业务层 <br />
应用程序在第二个session中调用update()保存修改 </span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt"><span style="color: red">三、delete操作</span> <br />
删除时直接自己构造一个project即可删除 <br />
this.projectDao.delete(preojct);</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">以前删除我是这样写的 <br />
public void deleteProject(String id) { <br />
Project project = (Project) this.projectDao.get(Project.class, id); <br />
if (project != null) { <br />
this.projectDao.delete(project); <br />
} <br />
即这样也是可以的 <br />
Project project = new Project(); <br />
project.setId(id); <br />
this.projectDao.delete(project).</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">如果有级联关系，需要把级联的子类也构造出来add进去，同样可以删除。</span></span></p>
<p><span style="font-family: 新宋体"><span style="font-size: 10pt">好了，罗嗦的够多了。</span></span></p>
<img src ="http://www.blogjava.net/migrant/aggbug/292815.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/migrant/" target="_blank">J2EE学习笔记</a> 2009-08-27 14:44 <a href="http://www.blogjava.net/migrant/archive/2009/08/27/292815.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Hibernate映射配置文件中id标签的unsaved-value属性详解</title><link>http://www.blogjava.net/migrant/archive/2009/08/17/291567.html</link><dc:creator>J2EE学习笔记</dc:creator><author>J2EE学习笔记</author><pubDate>Mon, 17 Aug 2009 14:41:00 GMT</pubDate><guid>http://www.blogjava.net/migrant/archive/2009/08/17/291567.html</guid><wfw:comment>http://www.blogjava.net/migrant/comments/291567.html</wfw:comment><comments>http://www.blogjava.net/migrant/archive/2009/08/17/291567.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/migrant/comments/commentRss/291567.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/migrant/services/trackbacks/291567.html</trackback:ping><description><![CDATA[<span style="font-family: 新宋体; font-size: 10pt">当你显式的使用session.save()或者session.update()操作一个对象的时候，实际上是用不到<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>的。某些情况下(父子表关联保存)，当你在程序中并没有显式的使用save或者update一个持久对象，那么<span style="font-family: " class="hilite1">Hibernate</span>需要判断被操作的对象究竟是一个已经持久化过的持久对象，是一个尚未被持久化过的内存临时对象。例如：<br />
<br style="font-family: " />
</span>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><span style="color: #000000">Session&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" />;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />Transaction&nbsp;tx&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" />;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />Parent&nbsp;parent&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Parent);&nbsp;session.load(Parent.</span><span style="color: #0000ff">class</span><span style="color: #000000">,&nbsp;id);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />Child&nbsp;child&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Child();;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />child.setParent(parent);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />child.setName(</span><span style="color: #000000">"</span><span style="color: #000000">sun</span><span style="color: #000000">"</span><span style="color: #000000">);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />parent.addChild(child);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />s.update(parent);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />s.flush();;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />tx.commit();;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />s.close();;</span></div>
<br />
<span style="font-family: 新宋体; font-size: 10pt">在上例中，程序并没有显式的session.save(child); 那么<span style="font-family: " class="hilite1">Hibernate</span>需要知道child究竟是一个临时对象，还是已经在数据库中有的持久对象。如果child是一个新创建的临时对象(本例中就是这种情况)，那么<span style="font-family: " class="hilite1">Hibernate</span>应该自动产生session.save(child)这样的操作，如果child是已经在数据库中有的持久对象，那么<span style="font-family: " class="hilite1">Hibernate</span>应该自动产生session.update(child)这样的操作。 <br style="font-family: " />
<br style="font-family: " />
因此我们需要暗示一下<span style="font-family: " class="hilite1">Hibernate</span>，究竟child对象应该对它自动save还是update。在上例中，显然我们应该暗示<span style="font-family: " class="hilite1">Hibernate</span>对child自动save，而不是自动update。那么<span style="font-family: " class="hilite1">Hibernate</span>如何判断究竟对child是save还是update呢？它会取一下child的主键属性 child.getId() ，这里假设id是 java.lang.Integer类型的。如果取到的Id值和hbm映射文件中指定的unsave-<span style="font-family: " class="hilite3">value</span>相等，那么<span style="font-family: " class="hilite1">Hibernate</span>认为child是新的内存临时对象，发送save，如果不相等，那么<span style="font-family: " class="hilite1">Hibernate</span>认为child是已经持久过的对象，发送update。 <br style="font-family: " />
<br style="font-family: " />
<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>="null" (默认情况，适用于大多数对象类型主键 Integer/Long/String/...) <br style="font-family: " />
<br style="font-family: " />
当<span style="font-family: " class="hilite1">Hibernate</span>取一下child的Id，取出来的是null(在上例中肯定取出来的是null)，和<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>设定值相等，发送save(child) <br style="font-family: " />
<br style="font-family: " />
当<span style="font-family: " class="hilite1">Hibernate</span>取一下child的id，取出来的不是null，那么和<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>设定值不相等，发送update(child) <br style="font-family: " />
<br style="font-family: " />
例如下面的情况：<br />
<br style="font-family: " />
</span>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><span style="color: #000000">Session&nbsp;session&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" />;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />Transaction&nbsp;tx&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;<img alt="" src="http://www.blogjava.net/Images/dot.gif" />;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />Parent&nbsp;parent&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Parent);&nbsp;session.load(Parent.</span><span style="color: #0000ff">class</span><span style="color: #000000">,&nbsp;id);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />Child&nbsp;child&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Child);&nbsp;session.load(Child.</span><span style="color: #0000ff">class</span><span style="color: #000000">,&nbsp;childId);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />child.setParent(parent);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />child.setName(</span><span style="color: #000000">"</span><span style="color: #000000">sun</span><span style="color: #000000">"</span><span style="color: #000000">);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />parent.addChild(child);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />s.update(parent);;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />s.flush();;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />tx.commit();;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />s.close();;</span></div>
<br />
<span style="font-family: 新宋体; font-size: 10pt">child已经在数据库中有了，是一个持久化的对象，不是新创建的，因此我们希望<span style="font-family: " class="hilite1">Hibernate</span>发送update(child)，在该例中，<span style="font-family: " class="hilite1">Hibernate</span>取一下child.getId()，和unsave-<span style="font-family: " class="hilite3">value</span>指定的null比对一下，发现不相等，那么发送update(child)。 <br style="font-family: " />
<br style="font-family: " />
BTW: parent对象不需要操心，因为程序显式的对parent有load操作和update的操作，不需要<span style="font-family: " class="hilite1">Hibernate</span>自己来判断究竟是save还是update了。我们要注意的只是child对象的操作。另外<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>是定义在Child类的主键属性中的。<br />
<br style="font-family: " />
</span>
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">class&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Child"</span><span style="color: #ff0000">&nbsp;table</span><span style="color: #0000ff">="child"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">id&nbsp;</span><span style="color: #ff0000">column</span><span style="color: #0000ff">="id"</span><span style="color: #ff0000">&nbsp;name</span><span style="color: #0000ff">="id"</span><span style="color: #ff0000">&nbsp;type</span><span style="color: #0000ff">="integer"</span><span style="color: #ff0000">&nbsp;unsaved-value</span><span style="color: #0000ff">="null"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">generator&nbsp;</span><span style="color: #ff0000">class</span><span style="color: #0000ff">="identity"</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">id</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">class</span><span style="color: #0000ff">&gt;</span></div>
<br />
<span style="font-family: 新宋体; font-size: 10pt">如果主键属性不是对象型，而是基本类型，如int/long/double/...，那么你需要指定一个数值型的<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>，例如：<br style="font-family: " />
</span><br />
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><span style="color: #000000">unsaved-value="0"</span></div>
<br />
<span style="font-family: 新宋体; font-size: 10pt">在此提醒大家，很多人以为对主键属性定义为int/long，比定义为Integer/Long运行效率来得高，认为基本类型不需要进行对象的封装和解构操作，因此喜欢把主键定义为int/long的。但实际上，<span style="font-family: " class="hilite1">Hibernate</span>内部总是把主键转换为对象型进行操作的，就算你定义为int/long型的，<span style="font-family: " class="hilite1">Hibernate</span>内部也要进行一次对象构造操作，返回给你的时候，还要进行解构操作，效率可能反而低也说不定。因此大家一定要扭转一个观点，在<span style="font-family: " class="hilite1">Hibernate</span>中，主键属性定义为基本类型，并不能够比定义为对象型效率来的高，而且也多了很多麻烦，因此建议大家使用对象型的Integer/Long定义主键。 <br style="font-family: " />
<br style="font-family: " />
<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>="none"和 <br style="font-family: " />
<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>="any" <br style="font-family: " />
<br style="font-family: " />
主主要用在主键属性不是通过<span style="font-family: " class="hilite1">Hibernate</span>生成，而是程序自己setId()的时候。 <br style="font-family: " />
<br style="font-family: " />
在这里多说一句，强烈建议使用<span style="font-family: " class="hilite1">Hibernate</span>的id generator，或者你可以自己扩展<span style="font-family: " class="hilite1">Hibernate</span>的id generator，特别注意不要使用有实际含义的字段当做主键来用！例如用户类User，很多人喜欢用用户登陆名称做为主键，这是一个很不好的习惯，当用户类和其他实体类有关联关系的时候，万一你需要修改用户登陆名称，一改就需要改好几张表中的数据。偶合性太高，而如果你使用无业务意义的id generator，那么修改用户名称，就只修改user表就行了。 <br style="font-family: " />
<br style="font-family: " />
由这个问题引申出来，如果你严格按照这个原则来设计数据库，那么你基本上是用不到手工来setId()的，你用<span style="font-family: " class="hilite1">Hibernate</span>的id generator就OK了。因此你也不需要了解当 <br style="font-family: " />
<br style="font-family: " />
<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>="none"和 <br style="font-family: " />
<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>="any" <br style="font-family: " />
<br style="font-family: " />
究竟有什么含义了。如果你非要用assigned不可，那么继续解释一下： <br style="font-family: " />
<br style="font-family: " />
<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>="none" 的时候，由于不论主键属性为任何值，都不可能为none，因此<span style="font-family: " class="hilite1">Hibernate</span>总是对child对象发送update(child) <br style="font-family: " />
<br style="font-family: " />
<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>="any" 的时候，由于不论主键属性为任何值，都肯定为any，因此<span style="font-family: " class="hilite1">Hibernate</span>总是对child对象发送save(child) <br style="font-family: " />
<br style="font-family: " />
大多数情况下，你可以避免使用assigned，只有当你使用复合主键的时候不得不手工setId()，这时候需要你自己考虑究竟怎么设置<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>了，根据你自己的需要来定。 <br style="font-family: " />
<br style="font-family: " />
BTW: Gavin King强烈不建议使用composite-id，强烈建议使用UserType。 <br style="font-family: " />
<br style="font-family: " />
因此，如果你在系统设计的时候，遵循如下原则： <br style="font-family: " />
<br style="font-family: " />
<span style="font-family: ; color: red">1、使用<span style="font-family: " class="hilite1">Hibernate</span>的id generator来生成无业务意义的主键，不使用有业务含义的字段做主键，不使用assigned。 <br style="font-family: " />
<br style="font-family: " />
2、使用对象类型(String/Integer/Long/...)来做主键，而不使用基础类型(int/long/...)做主键 <br style="font-family: " />
<br style="font-family: " />
3、不使用composite-id来处理复合主键的情况，而使用UserType来处理该种情况。</span> <br style="font-family: " />
<br style="font-family: " />
那么你永远用的是<span style="font-family: " class="hilite2">unsaved</span>-<span style="font-family: " class="hilite3">value</span>="null" ，不可能用到any/none/..了。 </span>
<img src ="http://www.blogjava.net/migrant/aggbug/291567.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/migrant/" target="_blank">J2EE学习笔记</a> 2009-08-17 22:41 <a href="http://www.blogjava.net/migrant/archive/2009/08/17/291567.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>