﻿<?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-Sealyu-随笔分类-EJB</title><link>http://www.blogjava.net/sealyu/category/30682.html</link><description>--- The devil's in the Details</description><language>zh-cn</language><lastBuildDate>Fri, 11 Jun 2010 17:14:13 GMT</lastBuildDate><pubDate>Fri, 11 Jun 2010 17:14:13 GMT</pubDate><ttl>60</ttl><item><title>illegal attempt to dereference collection(转)</title><link>http://www.blogjava.net/sealyu/archive/2010/04/23/319225.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Fri, 23 Apr 2010 14:44:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2010/04/23/319225.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/319225.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2010/04/23/319225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/319225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/319225.html</trackback:ping><description><![CDATA[<p>首先说一句：是版本的问题!</p>
<p>我写的hql为：</p>
<p>from Department as d where
d.employees.name='Tom';</p>
<p>运行时出现异常：org.hibernate.QueryException:
illegal attempt to dereference collection </p>
<p>是因为：在上面的HQL语句
中，Department的关联实体employees是一个集合，而不直接是一个Employee实体。</p>
<p>在
Hibernate3.2.2以前的版本，Hibernate会对关联实体自动使用隐式的inner join，</p>
<p>也就是说如下SQL语句
不会有任何问题&nbsp;:from Department as d where d.employees.name='Tom';</p>
<p>从
Hibernate3.2.3以后，Hibernate改变了这种隐式的inner join的策略 </p>
<p>对于如下这条语句：</p>
<p>from
Department as d where d.employees.name='Tom';</p>
<p>如果employees是普通组件属
性，或单个的关联实体，则Hibernate会自动生成隐式的inner join </p>
<p>如果myEvents是也一个集合，那么对不起！系
统将会出现 org.hibernate.QueryException: illegal attempt to dereference
collection异常。<br />
据Hibernate官方说法: <br />
这样可以让这使得隐含关联更具确定性（原文：This makes
implicit joins more deterministic ）。</p>
<p>推荐这样写：</p>
from Department as d inner join fetch
d.employees e where e.name='Tom';
<img src ="http://www.blogjava.net/sealyu/aggbug/319225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2010-04-23 22:44 <a href="http://www.blogjava.net/sealyu/archive/2010/04/23/319225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB3.0中关于Jpa的复合主键（转）</title><link>http://www.blogjava.net/sealyu/archive/2009/08/19/291730.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Wed, 19 Aug 2009 00:23:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/08/19/291730.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/291730.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/08/19/291730.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/291730.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/291730.html</trackback:ping><description><![CDATA[当我们需要使用一个或多个属性变量（表中的一列或多列）联合起来作为主键，我们需要使用复合主键。在EJB3.0中复合主键要求我们编写一个复合主键类(
Composite Primary Key Class )。下面是个小例子，在Student中要用sid和name做复合主键。<br />
Student实体类：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.persistence.Column;<br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.persistence.Entity;<br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.persistence.Id;<br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.persistence.IdClass;<br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">@Entity<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">@IdClass(StudentPK.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Student&nbsp;{<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;sid;<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;name;<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;age;<br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;@Id<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getSid()&nbsp;{<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;sid;<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setSid(String&nbsp;sid)&nbsp;{<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.sid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;sid;<br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;@Id<br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getName()&nbsp;{<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;name;<br />
</span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setName(String&nbsp;name)&nbsp;{<br />
</span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.name&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;name;<br />
</span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;@Column<br />
</span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getAge()&nbsp;{<br />
</span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;age;<br />
</span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setAge(String&nbsp;age)&nbsp;{<br />
</span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.age&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;age;<br />
</span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">}</span></div>
主键<span style="color: #000000;">StudentPK类：<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.io.Serializable;<br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;StudentPK&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Serializable{<br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span>&nbsp;<span style="color: #0000ff;">static</span>&nbsp;<span style="color: #0000ff;">final</span>&nbsp;<span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;serialVersionUID&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">1L</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;sid;<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;name;<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;StudentPK(){}<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;StudentPK(String&nbsp;sid,String&nbsp;name){<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.sid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;sid;<br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.name&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;name;<br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getSid()&nbsp;{<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;sid;<br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setSid(String&nbsp;sid)&nbsp;{<br />
</span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.sid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;sid;<br />
</span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getName()&nbsp;{<br />
</span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;name;<br />
</span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;setName(String&nbsp;name)&nbsp;{<br />
</span><span style="color: #008080;">26</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.name&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;name;<br />
</span><span style="color: #008080;">27</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">28</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">29</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
</span><span style="color: #008080;">30</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;hashCode()&nbsp;{<br />
</span><span style="color: #008080;">31</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">final</span>&nbsp;<span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;prime&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">31</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">32</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;result&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">1</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">33</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;prime&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;result&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;((name&nbsp;</span><span style="color: #000000;">==</span>&nbsp;<span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">?</span>&nbsp;<span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;:&nbsp;name.hashCode());<br />
</span><span style="color: #008080;">34</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;prime&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;result&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;((sid&nbsp;</span><span style="color: #000000;">==</span>&nbsp;<span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">?</span>&nbsp;<span style="color: #000000;">0</span><span style="color: #000000;">&nbsp;:&nbsp;sid.hashCode());<br />
</span><span style="color: #008080;">35</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result;<br />
</span><span style="color: #008080;">36</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">37</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">38</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
</span><span style="color: #008080;">39</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;equals(Object&nbsp;obj)&nbsp;{<br />
</span><span style="color: #008080;">40</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">this</span>&nbsp;<span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;obj)<br />
</span><span style="color: #008080;">41</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span>&nbsp;<span style="color: #0000ff;">true</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">42</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(obj&nbsp;</span><span style="color: #000000;">==</span>&nbsp;<span style="color: #0000ff;">null</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">43</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span>&nbsp;<span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">44</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(getClass()&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;obj.getClass())<br />
</span><span style="color: #008080;">45</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span>&nbsp;<span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">46</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;StudentPK&nbsp;other&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(StudentPK)&nbsp;obj;<br />
</span><span style="color: #008080;">47</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(name&nbsp;</span><span style="color: #000000;">==</span>&nbsp;<span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
</span><span style="color: #008080;">48</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(other.name&nbsp;</span><span style="color: #000000;">!=</span>&nbsp;<span style="color: #0000ff;">null</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">49</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span>&nbsp;<span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">50</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span>&nbsp;<span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">name.equals(other.name))<br />
</span><span style="color: #008080;">51</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span>&nbsp;<span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">52</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(sid&nbsp;</span><span style="color: #000000;">==</span>&nbsp;<span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
</span><span style="color: #008080;">53</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(other.sid&nbsp;</span><span style="color: #000000;">!=</span>&nbsp;<span style="color: #0000ff;">null</span><span style="color: #000000;">)<br />
</span><span style="color: #008080;">54</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span>&nbsp;<span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">55</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span>&nbsp;<span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">sid.equals(other.sid))<br />
</span><span style="color: #008080;">56</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span>&nbsp;<span style="color: #0000ff;">false</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">57</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span>&nbsp;<span style="color: #0000ff;">true</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">58</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">59</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080;">60</span>&nbsp;<span style="color: #000000;">}</span></div>
主键类必需满足下列条件：<br />
(1)必需被序列化<br />
(2)必需有一个公共的无参构造方法<br />
(3)必需实现equals()和hashCode()方法<br />
<br />
当你查询Student实体时必须使用主键类才能识别实体如:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;&nbsp;&nbsp; StudentPK&nbsp;pk&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;StudentPK(</span><span style="color: #000000;">"</span><span style="color: #000000;">bj1001</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">jakin</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;Student&nbsp;student&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;entityManager.find(Student.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;pk);</span></div>
在测试本例时笔者犯了两个低级的错误，一是测试环境的数据库不是项目运行的数据库，二是实体类中的属性命名用了关键字，请引以为戒。
<img src ="http://www.blogjava.net/sealyu/aggbug/291730.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-08-19 08:23 <a href="http://www.blogjava.net/sealyu/archive/2009/08/19/291730.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> EJB 3事务之容器管理事务（转）</title><link>http://www.blogjava.net/sealyu/archive/2009/07/20/287401.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Mon, 20 Jul 2009 01:37:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/07/20/287401.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/287401.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/07/20/287401.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/287401.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/287401.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">容器管理事务（<span>Container-Managed
Transaction, CMT</span>
）：容器管理事务允许组件自动征集（enlist
）到事务中，也就是说，EJB
组件从不需要显式地给出begin
、commit
、abort
语句，EJB
容器会替开发者考虑这些内容。EJB
容器会依据EJB
组件提供者指定的事务行为来界定相应的事务边界。在使用容器管理事务时，EJB
容器会拦截客户请求，并自动为EJB
组建启动新的事务，也就是说，容器会通过begin
语句调用底层事务系统，从而启动事务。随后，容器会将业务请求委派给EJB
组件，组件中的业务操作将运行在这一事务中。处于事务中的EJB
组件能够执行任何业务逻辑，如写入数据库、发送异步信息、调用其他的EJB
组件等。一旦在处理业务过程中出现问题，则EJB
组建需要通知EJB
容器去回滚事务。当EJB
组建完成业务处理后，会将控制权交回给EJB
容器。随后，EJB
容器能够通过commit
或abort
语句调用底层事务系统。
</span>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">通过使用@TransactionAttribute
注释或部署描述符，开发者能够指定事务属性。EJB
容器通过分析事务属性便能够知道如何处理EJB
组件的事务需求。EJB
事务属性的取值有：
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">（1
）Required
，如果EJB
组件必须总是运行在事务中，则应该使用Required
模式。如果已经有事务在运行，则EJB
组件参与其中；如果没有事务运行，则EJB
容器会为EJB
组件启动新的事务。
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">Required</span>
<span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">是默认和最常使用的事务属性值。这个值指定必须在事务之内调用EJB
方法。如果从非事务性客户端调用方法，那么容器会在调用方法之前开始事务，并且在方法返回时结束事务。另一方面，如果调用者从事务性上下文调用方法，那么
方法会联结已有事务。在从客户段传播事务的情况下，如果我们的方法表示应该回滚事务，那么容器不仅回回滚整个事务，而且会向客户端抛出异常，从而让客户端
知道它开始的事务已经被另一个方法回滚了。
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">（2
）Requires_New
，当客户调用EJB
时，如果总是希望启动新的事务，则应该使用RequiresNew
事务属性，如果客户在调用EJB
组件时已经存在事务，则当前事务会被挂起，进而容器启动新的事务，并将调用请求委派给EJB
组件。也就是说，如果客户端已经有了事务，那么它暂停该事务，知道方法返回位置，新事务是成功还是失败都不会影响客户端已有的事务。EJB
组件执行相应的业务操作，容器会提交或回滚事务，最终容器将恢复原有的事务，当然，如果客户在调用EJB
组件时不存在事务，则不需要执行事务的挂起或恢复操作。
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">RequiresNew</span>
<span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">事务属性非常有用。如果EJB
组件需要事务的ACID
属性，并且将EJB
组件运行在单个独立的工作单元中，从而不会将其他外部逻辑也包括在当前的事务中，则必须使用RequiredNew事
务属性。如果需要事务，但是不希望事务的回滚影响客户端，就应该使用它。另外，当不希望客户端的回滚影响你的时候，也应该使用这个值。日志记录是个很好的
例子，即使父事务回滚，你也希望把错误情况记录到日志中，另一方面，日志记录细小调试信息的失败不应该导致回滚整个事务，并且问题应该仅限于日志记录组件
内。
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">（3
）Supports
，如果某个EJB
组件使用了Supports
事务属性，则只有调用它的客户已经启用了事务时，这一EJB
组件才会运行在事务中。如果客户并没有运行在事务中，则EJB
组建也不会运行在事务中。Supports
同Required
事务属性很相似，但是，Required
要求EJB
组件必须运行在事务中。如果使用Support
事务属性，EJB
组建很可嫩没有运行在事务中。
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">（4
）Mandatory
，Mandatory
事务属性要求调用EJB
组件的客户必须已经运行在事务中。如果从非事务性客户端调用使用Mandatory
属性的EJB
方法，那么客户将接受到系统抛出的javax.ejb.EJBTransactionRequiredException
异常。EJB
组件使用Mandatory
事务属性是非常安全的，它能够保证EJB
组建运行在事务中。如果客户没有运行在事务中，则不能够调用到应用了Mandatory
事务属性的EJB
组件。但是，Mandatory
事务属性要求第3
方（及客户）在调用EJB
组件前必须启动了事务。EJB
容器并不会为Mandatory
事务属性自动启动新事务，这是同Support
事务属性的最主要区别。
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">（5
）NotSupported
，如果EJB
组件使用了NotSupport
事务属性，它根本不会参与到事务中。如果调用者使用相关联的事务调用方法，容器就会暂停事务，调用方法，然后再方法返回时恢复事务。通常，此属性只用于非实物性的自动确认模式中，支持JMS
提供者的MDB
。
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">（6
）Never
，如果EJB
组件使用Never
事务属性，它就不能够参与到事务中，而且，如果调用它的客户已经处于事务中，则容器会将javax.ejb.EJBException
异常抛给客户。
</span>
</p>
<p style="text-indent: 18.75pt; line-height: 150%;"><span style="font-size: 12pt; line-height: 150%; font-family: 宋体; color: black;">事务效果图，其中，T1
和T2
是2
个不同的事务，T1
是客户请求传递的事务，T2
是容器启动的事务，通过下表，能够理解各种事务属性在影响事务长度和范围方面所起的重要作用。
</span>
</p>
<div>
<table style="border-collapse: collapse;" border="0" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="padding: 3pt; background: #548dd4 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 136.1pt;" width="181">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体; color: white;">事务属性
            </span>
            </p>
            </td>
            <td style="padding: 3pt; background: #548dd4 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体; color: white;">客户事务
            </span>
            </p>
            </td>
            <td style="padding: 3pt; background: #548dd4 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; color: white;">EJB</span>
            <span style="font-size: 10pt; font-family: 宋体; color: white;">组件事务
            </span>
            </p>
            </td>
        </tr>
        <tr>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 136.1pt;" width="181">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">Required</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T2</span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
        </tr>
        <tr>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 136.1pt;" width="181">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">RequiresNew</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T2</span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T2</span>
            </p>
            </td>
        </tr>
        <tr>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 136.1pt;" width="181">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">Supports</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
        </tr>
        <tr>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 136.1pt;" width="181">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">Mandatory</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">错误
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
        </tr>
        <tr>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 136.1pt;" width="181">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">NotSupported</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            </td>
        </tr>
        <tr>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 136.1pt;" width="181">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">Never</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt;">T1</span>
            </p>
            </td>
            <td style="padding: 3pt; background: #d8e4f8 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 142.5pt;" width="190">
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">无
            </span>
            </p>
            <p style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: 宋体;">错误
            </span>
            </p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<img src ="http://www.blogjava.net/sealyu/aggbug/287401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-07-20 09:37 <a href="http://www.blogjava.net/sealyu/archive/2009/07/20/287401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>标注枚举类型@Enumerated（转）</title><link>http://www.blogjava.net/sealyu/archive/2009/06/30/284749.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Tue, 30 Jun 2009 05:18:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/06/30/284749.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/284749.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/06/30/284749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/284749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/284749.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">实体</span><font face="Times New Roman">Entity</font><span style="font-family: 宋体;">中通过</span><font face="Times New Roman">@Enumerated</font><span style="font-family: 宋体;">标注枚举类型，例如将</span><font face="Times New Roman">CustomerEO</font><span style="font-family: 宋体;">实体中增加一个</span><font face="Times New Roman">CustomerType</font><span style="font-family: 宋体;">类型的枚举型属性，标注实体后的代码如下所示。</span></font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">@Entity</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">@Table(name = "customer")</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">public class CustomerEO implements java.io.Serializable {</font></p>
<p style="margin: 0cm 0cm 0pt auto; text-indent: 21pt;"><span style="font-family: 黑体;"><font style="background-color: #e0e0e0;">&#8230;&#8230;</font></span></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private CustomerType type;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Enumerated(EnumType.STRING)</font></strong></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public CustomerType getType() {</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return type;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setType(CustomerType type) {</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.type = type;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public enum CustomerType {</font></strong></p>
<p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; COMPETITOR, INVESTOR, PARTNER, VENDER</font></strong></p>
<p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></strong></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">}</font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">在实体中虽然标注成枚举类型，但当实体持久化后，表中所对应的值仍旧是基本的数据类型，以上代码创建表的</span><font face="Times New Roman">SQL</font><span style="font-family: 宋体;">语句是：</span></font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">CREATE TABLE customer (</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id int(20) NOT NULL auto_increment,</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name varchar(255),</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type varchar(255),</font></strong></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PRIMARY KEY (id)</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">)</font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><span style="font-family: 宋体;"><font size="3">使用枚举类型后，在创建实体时便可以直接引用枚举类型，例如以下代码所示。</font></span></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">CustomerEO customer = new CustomerEO();</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">customer.setName("Janet2");</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">customer.setType(<strong>CustomerType.PARTNER</strong>);</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">entityManager.persist(customer);</font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">在使用</span><font face="Times New Roman">@Enumerated</font><span style="font-family: 宋体;">注释时，需要注意以下几个问题：</span></font></p>
<p style="margin: 0cm 0cm 0pt 21pt;"><span style="font-family: Wingdings;"><font size="3">l</font><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><font size="3"><span style="font-family: 宋体;">因为枚举类型的有名称和值两个属性，所以在持久化时可以选择持久化名称或是持久化值。通过</span><font face="Times New Roman">EnumType</font><span style="font-family: 宋体;">来定义，它有两个值如下所示。</span></font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">public enum EnumType {</font></p>
<p style="margin: 0cm 0cm 0pt auto; text-indent: 21pt;"><font style="background-color: #e0e0e0;">ORDINAL,</font></p>
<p style="margin: 0cm 0cm 0pt auto; text-indent: 21pt;"><font style="background-color: #e0e0e0;">STRING</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">}</font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">表示持久化的为枚举类型的值，</span><font face="Times New Roman">STRING</font><span style="font-family: 宋体;">表示持久化的为枚举类型的名称。默认为</span><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">，持久化值。例如以上示例中标注的为</span><font face="Times New Roman">STRING</font><span style="font-family: 宋体;">，这样持久化实体后，数据库中保存的是枚举类型的名称，如图</span><span style="font-family: 宋体;">所示。</span></font></p>
<p style="margin: 0cm 0cm 12pt;" align="center"><span style="font-family: 宋体;"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/EJB_JPA/5.5.jpg" /></span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">若此时改成</span><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">，代码如下：</span></font></p>
<p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Enumerated(EnumType.ORDINAL)</font></strong></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public CustomerType getType() {</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return type;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">则同样持久化的实体后，数据库保存的结果如图</span><span style="font-family: 宋体;">所示。</span></font></p>
<p style="margin: 0cm 0cm 12pt;" align="center"><span style="font-family: 宋体;"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/EJB_JPA/5.6.jpg" /></span></p>
<p style="margin: 0cm 0cm 0pt 21pt;"><span style="font-family: Wingdings;"><font size="3">l</font><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><font size="3"><span style="font-family: 宋体;">如何选择</span><font face="Times New Roman">STRING</font><span style="font-family: 宋体;">和</span><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">：</span></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">如果使用</span><font face="Times New Roman">STRING</font><span style="font-family: 宋体;">保存，虽然从数据库中查询数据时非常直观，能够清楚的看出该类型代表意义，但这样也会带来其他的问题。若此时枚举类型的定义改变，例如上例中的枚举类型名称改为：</span></font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public enum CustomerType {</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CUST_COMPETITOR, INVESTOR, PARTNER, VENDER</font></strong></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">则此时数据库中保存的&#8220;</span><font face="Times New Roman">COMPETITOR</font><span style="font-family: 宋体;">&#8221;的值将不能转化为枚举类型</span><font face="Times New Roman">CustomerType</font><span style="font-family: 宋体;">中的&#8220;</span><font face="Times New Roman">CUST_COMPETITOR</font><span style="font-family: 宋体;">&#8221;的值。但若使用</span><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">则不会带来这种问题。所以建议使用</span><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">类型来持久化枚举类型。</span></font></p>
<p style="margin: 0cm 0cm 0pt 21pt;"><span style="font-family: Wingdings;"><font size="3">l</font><span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><font size="3"><span style="font-family: 宋体;">枚举类型的定义位置，实体外部</span><font face="Times New Roman">VS</font><span style="font-family: 宋体;">实体内部。</span></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">上例中</span><font face="Times New Roman">CustomerType</font><span style="font-family: 宋体;">枚举类型定义在</span><font face="Times New Roman">CustomerEO</font><span style="font-family: 宋体;">实体内部，这是因为只有</span><font face="Times New Roman">CustomerEO</font><span style="font-family: 宋体;">这个实体会使用</span><font face="Times New Roman">CustomerType</font><span style="font-family: 宋体;">类型，其他的实体不会使用该类型。该类型与这个实体关系紧密联系。</span></font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">但若此时多个实体公用一个枚举类型时，则可以将枚举类型单独定义，定义在实体的外部。有这样一个枚举类型</span><font face="Times New Roman">BusinessLine</font><span style="font-family: 宋体;">，它定义在实体外部，代码如下：</span></font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">public enum BusinessLine {</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REAL_ESTATE,FINANCE, NON_PROFIT</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">}</font></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">例如</span><font face="Times New Roman">CustomerEO</font><span style="font-family: 宋体;">实体增加一个</span><font face="Times New Roman">BusinessLine</font><span style="font-family: 宋体;">的枚举类型，代码如下所示。</span></font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">@Entity</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">@Table(name = "customer")</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">public class CustomerEO implements java.io.Serializable {</font></p>
<p style="margin: 0cm 0cm 0pt auto; text-indent: 21pt;"><span style="font-family: 黑体;"><font style="background-color: #e0e0e0;">&#8230;&#8230;</font></span></p>
<p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private BusinessLine businessLine;</font></strong></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Enumerated(EnumType.STRING)</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public BusinessLine getBusinessLine() {</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return businessLine;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setBusinessLine(BusinessLine businessLine) {</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.businessLine = businessLine;</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">}</font></p>
<img src ="http://www.blogjava.net/sealyu/aggbug/284749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-06-30 13:18 <a href="http://www.blogjava.net/sealyu/archive/2009/06/30/284749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>javax.persistence.PersistenceException: org.hibernate.MappingException: Cannot use identity column key generation with &lt;union-subclass&gt; mapping for xxxxxxxxxxxxxxxx</title><link>http://www.blogjava.net/sealyu/archive/2009/02/09/253902.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Mon, 09 Feb 2009 06:19:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/02/09/253902.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/253902.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/02/09/253902.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/253902.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/253902.html</trackback:ping><description><![CDATA[今天在将ejb3的工程部署到jboss启动时报错：<br />
State: FAILED<br />
&nbsp; Reason: javax.persistence.PersistenceException: org.hibernate.MappingException: Cannot use identity column key generation with &lt;union-subclass&gt; mapping for: com.xxx.xxxx<br />
<br />
后来发现问题所在：<br />
<br />
继承策略我选择了@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)，<br />
同时在父类中设置了ID生成策略为：<br />
@Id<br />
&nbsp;&nbsp; &nbsp;@GeneratedValue(strategy=GenerationType.IDENTITY)<br />
&nbsp;&nbsp; &nbsp;public Long getId() {<br />
&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return id;<br />
&nbsp;&nbsp; &nbsp;}<br />
而在这种策略下使用unnion-subclass 元素时 父类的标识属性生成器不能使用&#8220;<font color="#ff0000"><strong>indentity&#8221;</strong></font> ，将策略改为
@GeneratedValue(strategy=GenerationType.TABLE)<br />
问题解决。<br />
<img src ="http://www.blogjava.net/sealyu/aggbug/253902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-02-09 14:19 <a href="http://www.blogjava.net/sealyu/archive/2009/02/09/253902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB/JPA继承详解(转)</title><link>http://www.blogjava.net/sealyu/archive/2009/01/05/249911.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Mon, 05 Jan 2009 06:18:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2009/01/05/249911.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/249911.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2009/01/05/249911.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/249911.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/249911.html</trackback:ping><description><![CDATA[因为关系数据库的表之间不存在继承关系，Entity 提供三种基本的继承映射策略：<br />
每个类分层结构一张表(table per class hierarchy)<br />
每个子类一张表(table per subclass)<br />
每个具体类一张表(table per concrete class)<br />
<br />
<font color="#ff0000">一、每个类分层结构一张表(table per class hierarchy)</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    这种映射方式只需为基类创建一个表即可。在表中不仅提供基类所有属性对应的字段，还要提供所有子类属性对应的字段，此外还需要一个字段用于区分子类的具体类型<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    要使用每个类分层结构一张表(table per class hierarchy) 策略，需要把<font color="#ff0000">@javax.persistence.Inheritance</font> 注释的<font color="#0000ff">strategy</font>属性设置为<font color="#3366ff">InheritanceType.SINGLE_TABLE</font>。除非你要改变子类的映射策略，否则<strong><font color="#ff0000">@Inheritance</font> 注释只能放在继承层次的基类</strong>。通过鉴别字段的值，持久化引掣可以区分出各个类，并且知道每个类对应那些字段。<font color="#cc99ff">鉴别字段</font>通过<font color="#ff0000">@javax.persistence.DiscriminatorColumn</font> 注释进行定义，<font color="#0000ff">name</font> 属性定义<font color="#cc99ff">鉴别字段的列名</font><font color="#0000ff"><font color="#000000">，</font>discriminatorType </font>属性定义<font color="#cc99ff">鉴别字段的类型</font>（可选值有：String, Char, Integer），如果鉴别字段的类型为String 或Char，可以用length 属性定义其长度。<font color="#ff0000">@DiscriminatorValue</font> 注释为继承关系中的<font color="#cc99ff">每个类定义鉴别值</font>，如果不指定鉴别值，默认采用类名<br />
例:<br />
&nbsp;&nbsp;&nbsp;    @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;    @Entity<br />
&nbsp;&nbsp;&nbsp;    @Table(name="Vehicle_Hierarchy")<br />
&nbsp;&nbsp;&nbsp;    <font color="#ff0000">@Inheritance(strategy=InheritanceType.SINGLE_TABLE)</font><br />
&nbsp;&nbsp;&nbsp;    @DiscriminatorColumn(name="Discriminator",<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    discriminatorType = DiscriminatorType.STRING,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    length=30)<br />
&nbsp;&nbsp;&nbsp;    @DiscriminatorValue("Vehicle")<br />
&nbsp;&nbsp;&nbsp;    <font color="#0000ff">public class Vehicle implements Serializable{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000"> //基类</font></font><br />
&nbsp;&nbsp;&nbsp;    private Long id;<br />
&nbsp;&nbsp;&nbsp;    private Short speed;//速度<br />
&nbsp;&nbsp;&nbsp;    @Id<br />
&nbsp;&nbsp;&nbsp;    @GeneratedValue<br />
&nbsp;&nbsp;&nbsp;    @Column(columnDefinition="integer")//指定使用适配Integer长度的数据类型<br />
&nbsp;&nbsp;&nbsp;    public Long getId() {<br />
&nbsp;&nbsp;&nbsp;    return id;<br />
&nbsp;&nbsp;&nbsp;    }<br />
&nbsp;&nbsp;&nbsp;    public void setId(Long id) {<br />
&nbsp;&nbsp;&nbsp;    this.id = id;<br />
&nbsp;&nbsp;&nbsp;    }<br />
<br />
&nbsp;&nbsp;&nbsp;   @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;   @Entity<br />
&nbsp;&nbsp;&nbsp;   @DiscriminatorValue("Car")<br />
&nbsp;&nbsp;&nbsp;   <font color="#0000ff">public class Car extends Vehicle{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000"> //Vehicle的子类</font></font><br />
&nbsp;&nbsp;&nbsp;   private String engine;//发动机<br />
&nbsp;&nbsp;&nbsp;   @Column(nullable=true,length=30)<br />
&nbsp;&nbsp;&nbsp;   public String getEngine() {<br />
&nbsp;&nbsp;&nbsp;   return engine;<br />
&nbsp;&nbsp;&nbsp;   }<br />
&nbsp;&nbsp;&nbsp;   public void setEngine(String engine) {<br />
&nbsp;&nbsp;&nbsp;   this.engine = engine;<br />
&nbsp;&nbsp;&nbsp;   &nbsp;&nbsp;&nbsp;   }<br />
&nbsp;&nbsp;&nbsp;   }<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;   @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;&nbsp;   @Entity<br />
&nbsp;&nbsp;&nbsp;&nbsp;   @DiscriminatorValue("Camion")<br />
&nbsp;&nbsp;&nbsp;&nbsp;   <font color="#0000ff">public class Camion extends Car{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   <font color="#ff0000">//Car的子类</font></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;   private String container;//集装箱<br />
&nbsp;&nbsp;&nbsp;&nbsp;   @Column(nullable=true,length=30)<br />
&nbsp;&nbsp;&nbsp;&nbsp;   public String getContainer() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;   return container;<br />
&nbsp;&nbsp;&nbsp;&nbsp;   }<br />
&nbsp;&nbsp;&nbsp;&nbsp;   public void setContainer(String container) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;   this.container = container;<br />
&nbsp;&nbsp;&nbsp;&nbsp;   &nbsp;&nbsp;&nbsp;&nbsp;   }<br />
&nbsp;&nbsp;&nbsp;&nbsp;   }<br />
<strong><font color="#ff0000">分析:</font></strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   <font color="#800080">可
以看出，每个子类没有单独的映射，在数据库中没有对应的表存在。而只有一个记录所有自身属性和子类所有属性的表，在基类为Vehicle
的时候，Discriminator 字段的值将为Vehicle,在子类为Car 的时候，Discriminator
字段的值将为Car，子类为Camion 的时候，Discriminator 字段的值将为Camion。那么，如果业务逻辑要求Car
对象的engine 属性不允许为null，显然无法在Vehicle_Hierarchy 表中为engine 字段定义not null
约束，可见这种映射方式无法保证关系数据模型的数据完整性。</font><br />
<br />
<font color="#ff0000">二、每个类分层结构一张表(table per class hierarchy)</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
这种映射方式为每个类创建一个表。在每个类对应的表中只需包含和这个类本身的属性对应的字段，子类对应的表参照父类对应的表,使用每个子类一张表
(table per subclass)策略，需要把@javax.persistence.Inheritance 注释的<strong>strategy </strong>属性设置为<strong>InheritanceType.JOINED<br />
<br />
</strong>&nbsp;&nbsp;&nbsp;&nbsp;  @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Entity<br />
&nbsp;&nbsp;&nbsp;&nbsp;  <font color="#ff0000">@Inheritance(strategy=InheritanceType.JOINED)</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Table(name="Vehicle")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  <font color="#0000ff">public class Vehicle implements Serializable{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#ff0000"> //基类</font></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;  private Long id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  private Short speed;//速度<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Id<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @GeneratedValue<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Column(columnDefinition="integer")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public Long getId() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  return id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public void setId(Long id) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  this.id = id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public Short getSpeed() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  return speed;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public void setSpeed(Short speed) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  this.speed = speed;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Entity<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Table(name="Car")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  <strong>@PrimaryKeyJoinColumn(name="CarID")&nbsp;&nbsp;&nbsp;&nbsp;  //把主键对应的列名更改为CarID</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;  <font color="#0000ff">public class Car extends Vehicle{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </font><font color="#0000ff"><font color="#ff0000">//Vehicle的子类</font></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;  private String engine;//发动机<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Column(nullable=true,length=30)<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public String getEngine() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  return engine;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public void setEngine(String engine) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  this.engine = engine;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Entity<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Table(name="Camion")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  <strong>@PrimaryKeyJoinColumn(name="CamionID")&nbsp;&nbsp;&nbsp;&nbsp;  //把主键对应的列名更改为CamionID</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;  <font color="#0000ff">public class Camion extends Car{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </font><font color="#0000ff"><font color="#ff0000">//Car的子类</font></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;  private String container;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Column(nullable=true,length=30)<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public String getContainer() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  return container;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public void setContainer(String container) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  this.container = container;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
<font color="#800080">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  这种映射方式支持多态关联和多态查询，而且符合关系数据模型的常规设计规则。在这种策略中你可以对子类的属性对应的字段定义not null 约束。该策略的缺点：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  它的查询性能不如上面介绍的映射策略。在这种映射策略下，必须通过表的内连接或左外连接来实现多态查询和多态关联。<br />
选择原则：子类属性非常多，需要对子类某些属性对应的字段进行not null 约束，且对性能要求不是很严格时，优先选择该策略</font><br />
<br />
<font color="#ff0000">三、每个具体类一张表(table per concrete class)</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
这种映射方式为每个类创建一个表。在每个类对应的表中包含和这个类所有属性（包括从超类继承的属性）对应的字段,使用每个具体类一张表(table
per concrete class)策略，需要把@javax.persistence.Inheritance 注释的<strong>strategy </strong>属性设置为<strong>InheritanceType.TABLE_PER_CLASS</strong><br />
<br />
<font color="#ff0000"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  注意:一旦使用这种策略就意味着你不能使用AUTO generator 和IDENTITY generator，即主键值不能采用数据库自动生成.</strong></font><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Entity<br />
&nbsp;&nbsp;&nbsp;&nbsp;  <font color="#ff0000">@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Table(name="Vehicle")<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff"> public class Vehicle implements Serializable{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </font><font color="#0000ff"><font color="#ff0000">//基类</font></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;  private Long id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  private Short speed;//速度<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Id<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Column(columnDefinition="integer")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public Long getId() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  return id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public void setId(Long id) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  this.id = id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public Short getSpeed() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  return speed;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public void setSpeed(Short speed) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  this.speed = speed;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Entity<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Table(name="Car")<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">public class Car extends Vehicle{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  &nbsp;&nbsp;  </font><font color="#0000ff"><font color="#ff0000">//Vehicle的子类</font></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;  private String engine;//发动机<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Column(nullable=true,length=30)<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public String getEngine() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  return engine;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public void setEngine(String engine) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  this.engine = engine;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @SuppressWarnings("serial")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Entity<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Table(name="Camion")<br />
&nbsp;&nbsp;&nbsp;&nbsp;  <font color="#ff0000"><font color="#0000ff">public class Camion extends Car{&nbsp;&nbsp;&nbsp;</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  </font><font color="#0000ff"><font color="#ff0000">//Car的子类</font></font><br />
&nbsp;&nbsp;&nbsp;&nbsp;  private String container;//集装箱<br />
&nbsp;&nbsp;&nbsp;&nbsp;  @Column(nullable=true,length=30)<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public String getContainer() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  return container;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  public void setContainer(String container) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;  this.container = container;<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
&nbsp;&nbsp;&nbsp;&nbsp;  }<br />
<br />
注意:在查询时,例如: <strong>from Vehicle v</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  查询所有Vehicle时，因为他是最继承树中的根，查询结果会得到所有继承于Vehicle类的记录<br />
<font color="#ff0000">(构造的SQL Where部分：<strong>where Discriminator in ('Car', 'Camion')</strong>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <font color="#000000"><strong>delete from Vehicle v</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  执行该操作会删除自身对应记录，还会删除所有继承Vehicle的记录,因为他是最继承树中的根，就相当于清除整个表的数据<br />
<br />
</font></font><font color="#800080">该策略的优点：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  在这种策略中你可以对子类的属性对应的字段定义not null 约束。<br />
该策略的缺点：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
不符合关系数据模型的常规设计规则，每个表中都存在属于基类的多余的字段。同时，为了支持策略的映射，持久化管理者需要决定使用什么方法，一种方法是在
entity
载入或多态关联时，容器使用多次查询去实现，这种方法需要对数据库做几次来往查询，非常影响执行效率。另一种方法是容器通过使用SQLUNIOU
查询来实现这种策略。<br />
选择原则：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  除非你的现实情况必须使用这种策略，一般情况下不要选择。</font>
<img src ="http://www.blogjava.net/sealyu/aggbug/249911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2009-01-05 14:18 <a href="http://www.blogjava.net/sealyu/archive/2009/01/05/249911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB3.1计划中的特性（转）</title><link>http://www.blogjava.net/sealyu/archive/2008/12/22/247720.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Mon, 22 Dec 2008 03:20:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2008/12/22/247720.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/247720.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2008/12/22/247720.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/247720.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/247720.html</trackback:ping><description><![CDATA[<p>
作者
<strong>Charles Humble</strong>译者
<strong>张龙</strong>
发布于
2008年3月20日 上午1时54分
</p>
<dl><dt>社区</dt><dd><a href="http://www.infoq.com/cn/java;jsessionid=C5BBED6FB1E114228CB758ED591CC199" name="java" id="739" onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;">Java</a></dd><dt>主题</dt><dd><a href="http://www.infoq.com/cn/EAB;jsessionid=C5BBED6FB1E114228CB758ED591CC199" name="EAB" id="3,713" onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;">Enterprise Application Blocks</a></dd><dt>标签</dt><dd><a href="http://www.infoq.com/cn/ejb;jsessionid=C5BBED6FB1E114228CB758ED591CC199" name="ejb" id="871" onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;">EJB</a>,</dd><dd><a href="http://www.infoq.com/cn/javaee5;jsessionid=C5BBED6FB1E114228CB758ED591CC199" name="javaee5" id="772" onclick="try {CategoryPopup.showPopup(this);} catch(e) {}; return false;">Java EE</a></dd></dl>
<p>EJB3.1专家组通过JCP发布了<u><font color="#0000ff">该</font></u><a id="qs4_" title="规范的早期草案" href="http://jcp.org/aboutJava/communityprocess/edr/jsr318/index.html">规范的早期草案</a> 。EJB的新版本期望作为2008年底发布的Java EE 6规范的一部分，它主要面向如下两个方面：简化工作（从EJB3开始）以及增加Java企业社区要求的新特性。主要改变如下：</p>
<ol>
    <li>一个简化的本地视图，无需单独的本地业务接口就可提供session bean的访问。通过这种方式，开发人员仅仅使用一个bean类就能实现一个组件。 </li>
    <li>一
    个单例session bean组件：在应用所运行的JVM上，针对每个应用仅实例化一次，该单例session
    bean组件的目的是为应用提供一个缓存状态的简单方法。作为一个EJB，该单例可以访问标准的EJB中间件服务集——事务管理、安全、远程、依赖注入等
    等。当容器调用session
    bean类的newInstance方法时该单例启动。默认情况下，由容器负责决定何时生成一个实例，然而开发者可以通过使用@Startup注解或者相
    应的部署描述符让实例在容器启动时就实例化。一个单例可能依赖另一个单例（通过@DependsOn注解标明），在这种情况下被依赖的单例就需要先实例
    化。单例session
    bean的生命周期与创建它的容器保持一致，但是其状态会因为JVM的停止或崩溃而丧失。因为其意在共享，所以它支持并发访问，这可由容器管理或者在每个
    bean中由开发者管理。 </li>
    <li>基于日历的EJB定时器表达式和自动创建的定时器：定时器服务可以通过使用类似于UNIX
    cron工具的基于日历的语法来表示定时器回调时间表。例如下面的时间表代表了&#8220;每周一、周三和周五的
    3：15&#8221;：@Schedule（minute=&#8220;15&#8221;, hour=&#8221;3&#8221;,
    dayOfWeek=&#8221;Mon,Wed,Fri&#8221;）。定时器服务也支持通过bean的元数据或者部署描述符自动创建定时器。自动创建的定时器是在应用部署
    时由容器创建的。 </li>
    <li>异步的session bean调用：默认情况下session
    bean在其调用期内会阻塞客户端。通过一个异步的方法调用，容器将控制权返还给客户端并且在一个单独的线程上继续处理该调用。一个异步方法能返回一个
    Future对象，该对象使得客户端可以获得一个结果值、检查异常或者尝试取消正在进行中的调用。 </li>
    <li>对于
    Enterprise JavaBeans功能的一个轻量级子集的定义，它们能够在Java EE Profiles内（如Java EE Web
    Profile）被提供，该子集将支持EJB3.1 APIs的如下部分：无状态、有状态以及单例session
    beans、本地业务视图与非接口视图（no-interface
    view）、同步方法调用、拦截器、声明式安全、容器管理的事务（CMT）划分、bean管理的事务（BMT）划分、企业bean环境、Java
    Persistence 2.0 API、JTA1.1的用户事务接口、Common Annotations 1.0以及由基本的Java SE
    6平台（JDBC、RMI-IIOP、JNDI、JAXP、Java
    IDL及JAAS）所支持的企业APIs。轻量级的EJB容器必须向企业bean实例提供一个JNDI
    API命名空间。打包的要求也得到了简化以便EJB组件可以直接打包到.war文件中——在这种情况下，EJB就驻留在WEB-INF/classes目
    录下而不再需要ejb-jar。其可选的ejb-jar.xml部署描述符放置在WEB-INF中。 </li>
</ol>
<p>规范的领导者Ken Saks已经开始撰写<a id="u_1y" title="博文" href="http://blogs.sun.com/kensaks/entry/ejb_3_1_early_draft">博文</a>以提供更多的关于专家组工作情况的信息，包括对通用EJB组件映射的支持：</p>
<blockquote>&#8220;对开发者来说造成挫败的一个共同的源泉就是用来解析和查找EJB引用的映射信息（如全局JNDI名）的不可移植性。我们不断探索以将该信息标准化使得应用无需特定于厂商的EJB组件映射就可以部署&#8221;</blockquote>
<p>专家组仍处在定义EJB3.1过程的早期阶段，所以上面列出来的特性有可能发生变化。这也是我们通过<a id="u1.i" title="邮件" href="http://jsr-318-comments@jcp.org/">邮件</a>向专家组提供反馈信息来参与到下一版规范的制定工作中去的绝佳机会。</p>
<img src ="http://www.blogjava.net/sealyu/aggbug/247720.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2008-12-22 11:20 <a href="http://www.blogjava.net/sealyu/archive/2008/12/22/247720.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Interceptor 中onFlushDirty()函数执行多次的问题（Hibernate 的一个小Bug）</title><link>http://www.blogjava.net/sealyu/archive/2008/05/09/199527.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Fri, 09 May 2008 07:59:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2008/05/09/199527.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/199527.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2008/05/09/199527.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/199527.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/199527.html</trackback:ping><description><![CDATA[最近在项目中遇到一个奇怪的问题，在使用Hibernate拦截器捕获实体变化并进行处理时，发现其中的onFlushDirty()函数执行了很多次，导致进行处理时产生很多重复数据。具体问题如下：<br />
使用一个类继承Hibernate的EmptyInterceptor类来对程序中的实体变化进行拦截，并在其中的onFlushDirty()函数中对捕获的数据进行处理，产生对应的event数据并保存到数据库中。 例如：<br />
public class EventInterceptor extends EmptyInterceptor {<br />
public boolean onFlushDirty(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object entity,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Serializable id,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object[] currentState,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object[] previousState,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] propertyNames,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Type[] types ) throws CallbackException {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(isAuditable(entity)){//如果该实体需要被记录，生成对应的event。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //此处生成对应的event。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br />
&nbsp;&nbsp;&nbsp; }<br />
<br />
在程序执行后，发现对应一条实体的变化生成了多条重复的event记录，非常不解。<br />
后来google发现，有人也碰到过对应的问题，并在Hibernage论坛中提出过这个问题，鉴定为Hibernate的一个小Bug。<br />
（原文地址：http://forum.hibernate.org/viewtopic.php?t=940410&amp;highlight=interceptor+onflushdirty）<br />
解决方法如下：<br />
将FlushMode改为：FlushMode.COMMIT<br />
或者也可以提前进行flush()<br />
都可以解决这个问题。<br />
<br />
<img src ="http://www.blogjava.net/sealyu/aggbug/199527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2008-05-09 15:59 <a href="http://www.blogjava.net/sealyu/archive/2008/05/09/199527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB3.0规范解读（转载）</title><link>http://www.blogjava.net/sealyu/archive/2008/04/10/192021.html</link><dc:creator>seal</dc:creator><author>seal</author><pubDate>Thu, 10 Apr 2008 15:05:00 GMT</pubDate><guid>http://www.blogjava.net/sealyu/archive/2008/04/10/192021.html</guid><wfw:comment>http://www.blogjava.net/sealyu/comments/192021.html</wfw:comment><comments>http://www.blogjava.net/sealyu/archive/2008/04/10/192021.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sealyu/comments/commentRss/192021.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sealyu/services/trackbacks/192021.html</trackback:ping><description><![CDATA[<table blogpost="" width="100%" border="0" cellspacing="0">
    <tbody>
        <tr>
            <td><span id="subjcns!C97D69BD51CBEFFA!139"><strong>EJB3.0规范解读</strong></span></td>
        </tr>
        <tr>
            <td><br />
            </td>
        </tr>
        <tr>
            <td id="msgcns!C97D69BD51CBEFFA!139">
            <div><font color="#008000" size="3"><strong>引言</strong></font>　　 <br />
            <br />
            在本文中将对新的规范进行一个概要性的介绍，包括新增的元数据支持，EJBQL的修改，实体Bean模型访问bean上下文的新方法和运行时环境等等。作者还讨论了EJB在未来要作出的调整以及EJB3.0与其他开发规范之间的关系。 <br />
            <br />
            <strong>开始</strong> <br />
            <br />
            无论如何由于EJB的复杂性使之在J2EE架构中的表现一直不是很好。EJB大概是J2EE架构中唯一一个没有兑现其能够简单开发并提高生产力的组建。
            EJB3.0规范正尝试在这方面作出努力以减轻其开发的复杂性。EJB3.0减轻了开发人员进行底层开发的工作量，它取消或最小化了很多（以前这些是必须
            实现）回调方法的实现，并且降低了实体Bean及O/R映射模型的复杂性。 <br />
            <br />
            在本文中，我首先会介绍EJB3.0中几个主要的改
            变。它对进一步深入了解EJB3.0是非常重要的。随后，我会从更高的层面来描述已经被提交到EJB3.0规范中的细节，并一个个的讲解新的规范中的改
            变：实体Bean,O/R映射模型，实体关系模型和EJB QL(EJB查询语言)等等。 <br />
            <br />
            <strong>背景</strong> <br />
            <br />
            EJB3.0中两个重要的变更分别是：使用了Java5中的程序注释工具和基于Hibernate的O/R映射模型。 <br />
            <br />
            <strong>Java5中的元数据工具</strong> <br />
            <br />
            Java5（以前叫J2SE1.5或Tiger）中加入了一种新的程序注释工具。通过这个工具你可以自定义注释标记，通过这些自定义标记来注释字段、方
            法、类等等。这些注释并不会影响程序的语义，但是可以通过工具（编译时或运行时）来解释这些标记并产生附加的内容（比如部署描述文件），或者强制某些必须
            的运行时行为（比如EJB组件的状态特性）。注释的解析可以通过源文件的解析（比如编译器或这IDE工具）或者使用Java5中的APIs反射机制。注释
            只能被定义在源代码层。由于所有被提交到EJB3.0草案中的注释标记都有一个运行时的RetentionPolicy，因此会增加类文件占用的存储空
            间，但这却给容器制造商和工具制造商带来了方便。</div>
            <div><br />
            <strong>Hibernate</strong> <br />
            <br />
            目前Hibernate非常受欢迎，它是开发源代码的Java
            O/R映射框架，目的是把开发人员从繁琐的数据持久化编程中解脱出来。它也有一个标准的HQL（Hibernate
            查询语言）语言，你可以在新的EJB
            QL中看到它的影子。Hibernate在处理如数据查询、更新、连接池、事务处理、实体关系处理等方面非常简单。 </div>
            <div>&nbsp;</div>
            <div><font color="#008000"><font size="3"><strong>深入研究</strong> </font></font><br />
            <br />
            现在是时候详细了解EJB3.0草案了。让我们开始探讨所有EJB中四种企业级bean，并看看他们在新的规范中是什么样子。 <br />
            <br />
            <strong>无状态会话bean</strong> <br />
            <br />
            在EJB3.0规范中，写一个无状态会话bean(SLSB)只需要一个简单的Java文件并在类层加上@Stateless注释就可以了。这个bean可以扩展javax.ejb.SessionBean接口，但这些不是必须的。 <br />
            <br />
            一个SLSB不再需要home接口，没有哪类EJB再需要它了。Bean类可以实现业务接口也可以不实现它。如果没有实现任何业务接口，业务接口会由任
            意public的方法产生。如果只有几个业务方法会被暴露在业务接口中，这些方法可以使用@BusinessMethod注释。缺省情况下所有产生的接口
            都是local（本地）接口，你也可以使用@Remote注释来声明这个接口为remote（远程）接口。 <br />
            <br />
            下面的几行代码就可以定义一个HelloWorldbean了。而在EJB2.1中同样的bean至少需要两个接口，一个实现类和几个空的实现方法，再加上部署描述符。　　 <br />
            <br />
            import javax.ejb.*; <br />
            <br />
            @Stateless <br />
            <br />
            @Remote <br />
            <br />
            public class HelloWorldBean { <br />
            <br />
            public String sayHello() { <br />
            <br />
            return "Hello World!!!"; <br />
            <br />
            } <br />
            <br />
            } <br />
            <br />
            <br />
            <strong>有状态会话bean</strong> <br />
            <br />
            除了几个SFSB的特别说明之外，有状态会话bean(SFSB)和SLSB一样精简： <br />
            <br />
            1)
            一个SFSB应该有一个方法来初始化自己（在EJB2.1中是通过ejbCreate()来实现的）。在EJB3.0的规范中建议这些初始化操作可以通过
            自定义方法完成，并把他们暴露在业务接口中。在使用这个bean之前由客户端来调用相应的初始化方法。目前规范组织就是否提供一个注释来标记某个方法用于
            初始化还存在争议。 <br />
            <br />
            2) Bean的提供者可以用@Remove注释来标记任何SFSB的方法，以说明这个方法被调用之后bean的实例将被移除。同样，规范组织仍然在讨论是否要有一种机制来处理这种特殊的情况，即当这个方法出现异常的情况下bean的实例是否被移除。 <br />
            <br />
            下面是对以上问题我个人的观点： <br />
            <br />
            1)
            是否应该有一个注释来标明一个方法进行初始化呢？我的观点是――应该有，这样容器就可以在调用其他方法之前至少调用一个方法来进行初始化。这不仅可以避免
            不必要的错误(由于没有调用初始化方法)而且可以使容器更明确的判断是否可以重用SFSB实例。我暂且把这个问题放一放，规范组织只考虑为一个方法提供一
            个注释来声明它是一个初始化方法。 <br />
            <br />
            2) 对于第二个问题我的观点也是肯定的。这有利于Bean的提供者合客户端程序对其进行控制。只有一个遗留的问题：那就是一旦调用这个方法失败，是否能移除这个bean 的实例？答案是不能，但是它将会在会话结束的时候被移除。 <br />
            <br />
            <strong>消息驱动Bean</strong> <br />
            <br />
            消息驱动Bean是唯一一种必须实现一个业务接口的Bean。这个接口指出bean支持的是哪一种消息系统。对于以JMS为基础的MDB来说，这个接口
            是javax.jms.MessageListener。注意MDB业务接口不是一个真正意义上的业务接口，它只是一个消息接口。 <br />
            <br />
            <strong>实体Bean</strong> <br />
            <br />
            1) 实体Bean使用@Entity注释来标记，所有实体bean中的属性/字段不必使用@Transient注释来标记。实体bean的持久化字段可以通过JavaBean-style机制或者声明为public/protected字段来实现。 <br />
            <br />
            2) 实体bean可以使用助手类来描述其状态，但是这些类的实例并没有持久化唯一性（persistent
            identity）的特性(即，唯一标识这个bean的字段等)，实际上这些助手类与他们的实体bean实例是紧密结合的；并且这些对象还是以非共享方式
            来访问实体对象的。 <br />
            <br />
            <strong>实体关联</strong> <br />
            <br />
            EJB3.0同时支持Bean之间双向的
            合单向的关联，它们可以是一对一、一对多、多对一或者是多对多的关联。然而双向关联的两端还要分为自身端（owning
            side）和对方端（inverse
            side）不同的端。自身端负责向数据库通告关联的变更。对于多对多的关联自身端必须明确的声明。实际上对方端通过isInverse=true进行注释
            （由此自身端就不必说明了而是由另一段推断出）。看来上面的描述，规范组织还能说让EJB变的简单了吗？ <br />
            <br />
            <strong>O/R映射</strong> <br />
            <br />
            EJB3.0中的O/R映射模型也有了重要的改变，它从原来的abstract-persistence-schema-based变成了现在的
            Hibernate-inspired模式。尽管目前规范组织还在就此进行讨论但是一个明确的模型将会出现在下一个版本的草案中。 <br />
            <br />
            举例来说，O/R映射模型将通过bean类中的注释来声明。而且此方法还会指出对应的具体表和字段。O/R映射模型提供了一套自有的SQL；而且除了提
            供一些基本的SQL外还支持某些高层开发的功能。比如，有一个通过@Column注释声明的字段columnDefinition，那么可以写这样的
            SQL：columnDefinition="BLOB NOT NULL"</div>
            <div>&nbsp;</div>
            <div><font color="#008000"><strong><font size="3">客户端程序模型</font></strong> <br />
            </font><br />
            一个EJB客户端可以通过@Inject注释以一种&#8220;注入&#8221;的方式获得一个bean的业务接口引用。你也可以使用另一个注释
            @javax.ejb.EJBContext.lookup()来完成上面的操作，但是规范中没有告诉我们一个普通的Java客户端怎样获得一个Bean
            的实例，因为这个普通的Java客户端是运行在一个客户端容器中，它无法访问@javax.ejb.EJBContex对象。现在还有另外一种机制来完成
            上面的工作那就是使用一个超级上下文环境对象：@javax.ejb.Context()。但是规范中没有指出该如何在客户端中使用这个对象。 <br />
            <br />
            <strong>EJB QL</strong> <br />
            <br />
            EJB
            QL可以通过@NamedQuery来注释。这个注释有两个成员属性分别是name和queryString.一旦定义了这些属性，就可以通过
            EntityManager.createNamedQuery(name)来指向这个查询。你也可以创建一个标准的JDBC风格的查询并使用
            EntityManager.createQuery(ejbqlString)或EntityManager.createNativeQuery
            (nativeSqlString)(这个方法用于执行一个本地查询)来执行查询。 <br />
            <br />
            EJB QL有两个地方可以定义其参数。javax.ejb.Query接口提供了定义参数、指向查询、更新数据等等方法。下面是一个EJBQL指向查询的例子： <br />
            <br />
            .. .. <br />
            <br />
            @NamedQuery( <br />
            <br />
            name="findAllCustomersWithName", <br />
            <br />
            queryString="SELECT c FROM Customer c WHERE c.name LIKE :custName" <br />
            <br />
            ) <br />
            <br />
            .. .. <br />
            <br />
            @Inject public EntityManager em; <br />
            <br />
            customers = em.createNamedQuery("findAllCustomersWithName") <br />
            <br />
            .setParameter("custName", "Smith") <br />
            <br />
            .listResults(); <br />
            <br />
            <br />
            <br />
            下面列出了一些EJB QL的增强特性： <br />
            <br />
            1) 支持批量更新和删除。 <br />
            <br />
            2) 直接支持内连接和外连接。FETCH JOIN运行你指出关联的实体，Order可以指定只查询某个字段。 <br />
            <br />
            3) 查询语句可以返回一个以上的结果值。实际上，你可以返回一个依赖的类比如下面这样：　　 <br />
            <br />
            SELECT new CustomerDetails(c.id, c.status, o.count) <br />
            <br />
            FROM Customer c JOIN c.orders o <br />
            <br />
            WHERE o.count &gt; 100　　 <br />
            <br />
            4) 支持group by 和having。 <br />
            <br />
            5) 支持where子句的嵌套子查询。 <br />
            <br />
            在提交的EJB3.0草案中，EJB QL与标准SQL非常的接近。实际上规范中甚至直接支持本地的SQL(就像我们上面提到的那样)。这一点对某些程序员来说也许有些不是很清楚，我们将在下面进行更详细的讲解。 <br />
            <br />
            <strong>多样性</strong> <br />
            <br />
            方法许可(Method
            permissions)可以通过@MethodPermissions或@Unchecked注释来声明；同样的，事务属性也可以通过
            @TransactionAttribute注释来声明。规范中仍然保留资源引用和资源环境引用。这些一样可以通过注释来声明，但是有一些细微的差别。比
            如，上下文(context)环境要通过注入工具控制。容器根据bean对外部环境引用自动初始化一个适当的已经声明的实例变量。比如，你可以象下面这样
            获得一个数据源（DataSource）：　　 <br />
            <br />
            @Resource(name="myDataSource") //Type is inferred from variable <br />
            <br />
            public DataSource customerDB; <br />
            <br />
            在上面的例子中如果你不指定引用资源的名称(name)那么其中的customerDB会被认为是默认值。当所有的引用属性都可得到时，@Injec注释就可以这样写：　　 <br />
            <br />
            @Inject public DataSource customerDB; <br />
            <br />
            容器负责在运行时初始化customerDB数据源实例。部署人员必须在此之前在容器中定义好这些资源属性。 <br />
            <br />
            更好的消息是：那些以前必须检测的异常将一去不复返。你可以声明任意的应用程序异常，而不必在再抛出或捕获其他类似CreateException和
            FinderException这样的异常。容器会抛出封装在javax.ejb.EJBException中的系统级异常或者只在必要时候抛出
            IllegalArgumentException或IllegalStateException异常。</div>
            <div>&nbsp;</div>
            <div><strong><font size="3">EJB文件处理模式</font></strong> <br />
            <br />
            在我们结束本节之前，让我的快速的浏览一下容器提供商在EJB处理模式方面可能的变更。规范中对此并没有明确的表态，但我可以想到至少两种模式。 <br />
            <br />
            1)
            一种办法是首先利用EJB文件生成类似于EJB2.1部署模式的文件（包括必要的接口和部署描述符）然后再用类似于EJB2.1的方式来部署这个EJB组
            件。当然，这样产生的部署描述符可能并不标准但是它可以解决同一个容器对EJB2.1和EJB3.0兼容的问题。　　 <br />
            <br />
            2)
            另一种方法是一种类似于JSP托放的部署模式。你可以把一个EJB文件放到一个预先定义的目录下，然后容器会识别这个EJB并处理它，然后部署并使之可以
            使用。这种方法可以建立于上面那种方法之上，在支持反复部署时有很大的帮助。考虑到部署的简单性也是EJB3.0规范的目的之一，我真诚的希望在下一个草
            案出来时能够确定一个模式(至少能有一个非正式的)。 <br />
            <br />
            你有什么想法？ <br />
            <br />
            EJB3.0规范的制定正在有序的进
            行，为了使EJB的开发变得更加容易，EJB规范组织作出的努力是有目共睹的。就像他们说的那样，一切对会变得简单，但做到这一点并不容易。目前已经定义
            了50个注释标记(还有几个将在下一个草案中发布)，每一个都有自己的缺省规则和其他的操作。当然，我真的不希望EJB3.0变成EJB2.1的一个翻版
            "EJB 3.0 = EJB 2.1 for dummies"（希望这个等式不要成立）。最后，我还是忍不住要提一些我自己的观点： <br />
            <br />
            1) 首先，规范确实使反复部署变得容易了，并且有一个简单的模式来访问运行时环境。我还是觉得home接口应该放弃。 <br />
            <br />
            2)
            在早期的EJB规范中，实体bean用于映射一个持久化存储。理论上(也许只是理论上)可能需要把实体bean映射到一个遗留的EIS
            (enterprise information
            system)系统中。出于将来扩展的考虑这样作是有好处的，并且可以使更多的业务数据模型采用实体bean。也因此其伴随的复杂性使得实体bean不被
            看好。在本次提交的草案中，一个实体bean只是一个数据库的映射。并且是基于非抽象持久化模式和简单的数据访问模式的更加简单开发。 <br />
            <br />
            3)
            我对模型变更持保留态度，我认为在EJB中包含SQL脚本片断并不是个好注意。一些开发人员完全反对包含某些&#8220;SQL片段（SQLness）&#8221;（比如
            @Table 和
            @Column注释）。我的观点是这些SQLness是好的，据此我们可以清楚的知道我们到底要数据库作些什么。但是某些SQL段我看来并不是很好，比如
            columnDefinition="BLOB NOT NULL"，这使得EJB代码和SQL之间的耦合太过紧密了。 <br />
            <br />
            4) 尽管对于本地SQL的支持看似很诱人，其实在EJB代码中嵌入SQL是一个非常糟糕的主意。当然，有些办法可以避免在EJB中硬编码SQL，但是这应该在规范中说明，而不能是某些开发人员自己定义的模式。 <br />
            <br />
            5) 假设@Table注释只用于类。在运行时通过@Table注释的name属性定义的表名称将必须对应一个实际的数据库表。规范对此应该给予清楚的说明和一致的模式。 <br />
            <br />
            6) 规范还需要更清楚的说明客户端编程模型，尤其是普通java客户端。规范中所有的参考都假设或者隐含的使用EJB客户端。而且规范中对客户端的向后兼容方面也没有给出明确的说法。 <br />
            <br />
            7)
            Transient注释应该重新命名以避免和已有的transient关键字发生冲突。事实上，在这一点上我们更乐于稍微的背离一下
            configuration-by-exception原则并且定义一个@Persistent注释来明确的定义持久化字段。@Persistent注释
            可以仅仅是一个标记注释或者它可以有几个属性来关联O/R映射注释。 <br />
            <br />
            与其他规范的关联 <br />
            <br />
            目前可能影响到EJB3.0的JSR有JSR175（java语言元数据工具）和JSR181（Java Web服务元数据） <br />
            <br />
            JSR175已经初步完成并且不会和EJB3.0有太大的冲突；但是JSR181与EJB3.0有两个关联的地方： <br />
            <br />
            1) Web service接口：EJB规范将采用一种机制适应JSR181以便可以把一个bean实现为一个Web service并告诉Web service如何被客户端调用。 <br />
            <br />
            2) JSR
            181计划采用不同的机制来处理安全问题。在早期的规范中EJB建议使用一个一致的机制（MethodPermissions），但是JSR
            181计划使用一个稍微不同的方式（SecurityRoles和SecurityIdentity注释）。同样的RunAs注释的定义也存在这些许差
            别。这一问题还在解决中最终会在J2EE层的规范中维持其一致性。 <br />
            <br />
            在J2EE 1.5中的一些开发规范可能与EJB3.0有关联。除了上面说到的几个关联之外现在没有其他的开发规范与EJB3.0有冲突。 <br />
            <br />
            结束语 <br />
            <br />
            在使EJB的开发变得简单高效之前，我们还有很长一段路要走。规范组织在降低EJB的开发难度方面起了个好头。O/R映射模型的提议还处在早期阶段，规范组织正在完善它。我希望它不要太复杂也不要与SQL过分的耦合。</div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.blogjava.net/sealyu/aggbug/192021.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sealyu/" target="_blank">seal</a> 2008-04-10 23:05 <a href="http://www.blogjava.net/sealyu/archive/2008/04/10/192021.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>