??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲午夜av,中文在线播放,自拍偷拍亚洲一区http://www.aygfsteel.com/sealyu/category/30682.html--- The devil's in the Detailszh-cnFri, 11 Jun 2010 17:14:13 GMTFri, 11 Jun 2010 17:14:13 GMT60illegal attempt to dereference collection(?http://www.aygfsteel.com/sealyu/archive/2010/04/23/319225.htmlsealsealFri, 23 Apr 2010 14:44:00 GMThttp://www.aygfsteel.com/sealyu/archive/2010/04/23/319225.htmlhttp://www.aygfsteel.com/sealyu/comments/319225.htmlhttp://www.aygfsteel.com/sealyu/archive/2010/04/23/319225.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/319225.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/319225.html首先说一句:(x)是版本的问题!

我写的hql为:(x)

from Department as d where d.employees.name='Tom';

q行时出现异常:(x)org.hibernate.QueryException: illegal attempt to dereference collection

是因为:(x)在上面的HQL语句 中,Department的关联实体employees是一个集合,而不直接是一个Employee实体?/p>

? Hibernate3.2.2以前的版本,Hibernate?x)对兌实体自动使用隐式的inner joinQ?/p>

也就是说如下SQL语句 不会(x)有Q何问?nbsp;:from Department as d where d.employees.name='Tom';

? Hibernate3.2.3以后QHibernate改变?sh)(jin)这U隐式的inner join的策?

对于如下q条语句Q?/p>

from Department as d where d.employees.name='Tom';

如果employees是普通组件属 性,或单个的兌实体Q则Hibernate?x)自动生成隐式的inner join

如果myEvents是也一个集合,那么对不Pp? l将?x)出?org.hibernate.QueryException: illegal attempt to dereference collection异常?br /> 据Hibernate官方说法:
q样可以让这使得隐含兌更具定性(原文QThis makes implicit joins more deterministic Q?/p>

推荐q样写:(x)

from Department as d inner join fetch d.employees e where e.name='Tom';

seal 2010-04-23 22:44 发表评论
]]>
EJB3.0中关于Jpa的复合主键(转)(j)http://www.aygfsteel.com/sealyu/archive/2009/08/19/291730.htmlsealsealWed, 19 Aug 2009 00:23:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/08/19/291730.htmlhttp://www.aygfsteel.com/sealyu/comments/291730.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/08/19/291730.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/291730.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/291730.html Student实体c:(x)
 1 import javax.persistence.Column;
 2 import javax.persistence.Entity;
 3 import javax.persistence.Id;
 4 import javax.persistence.IdClass;
 5 
 6 @Entity
 7 @IdClass(StudentPK.class)
 8 public class Student {
 9     
10     private String sid;
11     private String name;
12     private String age;
13 
14     @Id
15     public String getSid() {
16         return sid;
17     }
18     public void setSid(String sid) {
19         this.sid = sid;
20     }
21     
22     @Id
23     public String getName() {
24         return name;
25     }
26     public void setName(String name) {
27         this.name = name;
28     }
29     
30     @Column
31     public String getAge() {
32         return age;
33     }
34     public void setAge(String age) {
35         this.age = age;
36     }
37 
38 }
主键StudentPKc:(x)
 1 import java.io.Serializable;
 2 
 3 public class StudentPK implements Serializable{
 4     
 5     private static final long serialVersionUID = 1L;
 6     
 7     private String sid;
 8     private String name;
 9     
10     public StudentPK(){}
11     public StudentPK(String sid,String name){
12         this.sid = sid;
13         this.name = name;
14     }
15     
16     public String getSid() {
17         return sid;
18     }
19     public void setSid(String sid) {
20         this.sid = sid;
21     }
22     public String getName() {
23         return name;
24     }
25     public void setName(String name) {
26         this.name = name;
27     }
28     
29     @Override
30     public int hashCode() {
31         final int prime = 31;
32         int result = 1;
33         result = prime * result + ((name == null? 0 : name.hashCode());
34         result = prime * result + ((sid == null? 0 : sid.hashCode());
35         return result;
36     }
37     
38     @Override
39     public boolean equals(Object obj) {
40         if (this == obj)
41             return true;
42         if (obj == null)
43             return false;
44         if (getClass() != obj.getClass())
45             return false;
46         final StudentPK other = (StudentPK) obj;
47         if (name == null) {
48             if (other.name != null)
49                 return false;
50         } else if (!name.equals(other.name))
51             return false;
52         if (sid == null) {
53             if (other.sid != null)
54                 return false;
55         } else if (!sid.equals(other.sid))
56             return false;
57         return true;
58     }
59     
60 }
主键cd需满下列条gQ?br /> (1)必需被序列化
(2)必需有一个公q无参构造方?br /> (3)必需实现equals()和hashCode()Ҏ(gu)

当你查询Student实体时必M用主键类才能识别实体?
    StudentPK pk = new StudentPK("bj1001","jakin");
    Student student 
= entityManager.find(Student.class, pk);
在测试本例时W者犯?jin)两个低U的错误Q一是测试环境的数据库不是项目运行的数据库,二是实体cM的属性命名用?jin)关键字Q请引以为戒?

seal 2009-08-19 08:23 发表评论
]]>
EJB 3事务之容器管理事务(转)(j)http://www.aygfsteel.com/sealyu/archive/2009/07/20/287401.htmlsealsealMon, 20 Jul 2009 01:37:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/07/20/287401.htmlhttp://www.aygfsteel.com/sealyu/comments/287401.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/07/20/287401.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/287401.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/287401.html容器理事务Q?span>Container-Managed Transaction, CMT Q:(x)容器理事务允许lg自动征集Qenlist Q到事务中,也就是说QEJB lg从不需要显式地l出begin 、commit 、abort 语句QEJB 容器?x)替开发者考虑q些内容。EJB 容器?x)依据EJB lg提供者指定的事务行ؓ(f)来界定相应的事务边界。在使用容器理事务ӞEJB 容器?x)拦截客戯求,q自动ؓ(f)EJB l徏启动新的事务Q也是_(d)容器?x)通过begin 语句调用底层事务pȝQ从而启动事务。随后,容器?x)将业务h委派lEJB lgQ组件中的业务操作将q行在这一事务中。处于事务中的EJB lg能够执行M业务逻辑Q如写入数据库、发送异步信息、调用其他的EJB lg{。一旦在处理业务q程中出现问题,则EJB l徏需要通知EJB 容器d滚事务。当EJB l徏完成业务处理后,?x)将控制权交回给EJB 容器。随后,EJB 容器能够通过commit 或abort 语句调用底层事务pȝ?

通过使用@TransactionAttribute 注释或部|描q符Q开发者能够指定事务属性。EJB 容器通过分析事务属性便能够知道如何处理EJB lg的事务需求。EJB 事务属性的取值有Q?

Q? QRequired Q如果EJB lg必须Lq行在事务中Q则应该使用Required 模式。如果已l有事务在运行,则EJB lg参与其中Q如果没有事务运行,则EJB 容器?x)?f)EJB lg启动新的事务?

Required 是默认和最怋用的事务属性倹{这个值指定必d事务之内调用EJB Ҏ(gu)。如果从非事务性客L(fng)调用Ҏ(gu)Q那么容器会(x)在调用方法之前开始事务,q且在方法返回时l束事务。另一斚wQ如果调用者从事务性上下文调用Ҏ(gu)Q那? Ҏ(gu)?x)联l已有事务。在从客h传播事务的情况下Q如果我们的Ҏ(gu)表示应该回滚事务Q那么容器不仅回回滚整个事务Q而且?x)向客户端抛出异常,从而让客户? 知道它开始的事务已经被另一个方法回滚了(jin)?

Q? QRequires_New Q当客户调用EJB Ӟ如果L希望启动新的事务Q则应该使用RequiresNew 事务属性,如果客户在调用EJB lg时已l存在事务,则当前事务会(x)被挂Pq而容器启动新的事务,q将调用h委派lEJB lg。也是_(d)如果客户端已l有?jin)事务,那么它暂停该事务Q知道方法返回位|,C务是成功q是p|都不?x)?jing)响客L(fng)已有的事务。EJB lg执行相应的业务操作,容器?x)提交或回滚事务Q最l容器将恢复原有的事务,当然Q如果客户在调用EJB lg时不存在事务Q则不需要执行事务的挂v或恢复操作?

RequiresNew 事务属性非常有用。如果EJB lg需要事务的ACID 属性,q且EJB lgq行在单个独立的工作单元中,从而不?x)将其他外部逻辑也包括在当前的事务中Q则必须使用RequiredNew? 务属性。如果需要事务,但是不希望事务的回滚影响客户端,应该用它。另外,当不希望客户端的回滚影响你的时候,也应该用这个倹{日志记录是个很好的 例子Q即使父事务回滚Q你也希望把错误情况记录到日志中Q另一斚wQ日志记录细调试信息的p|不应该导致回滚整个事务,q且问题应该仅限于日志记录组? 内?

Q? QSupports Q如果某个EJB lg使用?jin)Supports 事务属性,则只有调用它的客户已l启用了(jin)事务Ӟq一EJB lg才会(x)q行在事务中。如果客户ƈ没有q行在事务中Q则EJB l徏也不?x)运行在事务中。Supports 同Required 事务属性很怼Q但是,Required 要求EJB lg必须q行在事务中。如果用Support 事务属性,EJB l徏很可嫩没有运行在事务中?

Q? QMandatory QMandatory 事务属性要求调用EJB lg的客户必dl运行在事务中。如果从非事务性客L(fng)调用使用Mandatory 属性的EJB Ҏ(gu)Q那么客户将接受到系l抛出的javax.ejb.EJBTransactionRequiredException 异常。EJB lg使用Mandatory 事务属性是非常安全的,它能够保证EJB l徏q行在事务中。如果客h有运行在事务中,则不能够调用到应用了(jin)Mandatory 事务属性的EJB lg。但是,Mandatory 事务属性要求第3 方(?qing)客P(j)在调用EJB lg前必d动了(jin)事务。EJB 容器q不?x)?f)Mandatory 事务属性自动启动新事务Q这是同Support 事务属性的最主要区别?

Q? QNotSupported Q如果EJB lg使用?jin)NotSupport 事务属性,它根本不?x)参与到事务中。如果调用者用相兌的事务调用方法,容器׃(x)暂停事务Q调用方法,然后再方法返回时恢复事务。通常Q此属性只用于非实物性的自动认模式中,支持JMS 提供者的MDB ?

Q? QNever Q如果EJB lg使用Never 事务属性,它就不能够参与到事务中,而且Q如果调用它的客户已l处于事务中Q则容器?x)将javax.ejb.EJBException 异常抛给客户?

事务效果图,其中QT1 和T2 ? 个不同的事务QT1 是客戯求传递的事务QT2 是容器启动的事务Q通过下表Q能够理解各U事务属性在影响事务长度和范围方面所L(fng)重要作用?

事务属?

客户事务

EJB lg事务

Required

?

T1

T2

T1

RequiresNew

?

T1

T2

T2

Supports

?

T1

?

T1

Mandatory

?

T1

错误

T1

NotSupported

?

T1

?

?

Never

?

T1

?

错误



seal 2009-07-20 09:37 发表评论
]]>
标注枚Dcd@EnumeratedQ{Q?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/sealyu/archive/2009/06/30/284749.html</guid><wfw:comment>http://www.aygfsteel.com/sealyu/comments/284749.html</wfw:comment><comments>http://www.aygfsteel.com/sealyu/archive/2009/06/30/284749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sealyu/comments/commentRss/284749.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/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: 宋体;">标注枚DcdQ例如将</span><font face="Times New Roman">CustomerEO</font><span style="font-family: 宋体;">实体中增加一?/span><font face="Times New Roman">CustomerType</font><span style="font-family: 宋体;">cd的枚丑֞属性,标注实体后的代码如下所C?/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;">……</font></span></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         private CustomerType type;</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;"> </font></p> <p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">         @Enumerated(EnumType.STRING)</font></strong></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         public CustomerType getType() {</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">                   return type;</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         }</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;"> </font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         public void setType(CustomerType type) {</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">                   this.type = type;</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         }</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;"> </font></p> <p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">         public enum CustomerType {</font></strong></p> <p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">                   COMPETITOR, INVESTOR, PARTNER, VENDER</font></strong></p> <p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">         }</font></strong></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;"> </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: 宋体;">在实体中虽然标注成枚丄型,但当实体持久化后Q表中所对应的g旧是基本的数据类型,以上代码创徏表的</span><font face="Times New Roman">SQL</font><span style="font-family: 宋体;">语句是:(x)</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;">         id int(20) NOT NULL auto_increment,</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         name varchar(255),</font></p> <p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">         type varchar(255),</font></strong></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         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">使用枚Dcd后,在创建实体时便可以直接引用枚丄型,例如以下代码所C?/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: 宋体;">注释Ӟ需要注意以下几个问题:(x)</span></font></p> <p style="margin: 0cm 0cm 0pt 21pt;"><span style="font-family: Wingdings;"><font size="3">l</font><span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">         </span></span><font size="3"><span style="font-family: 宋体;">因ؓ(f)枚Dcd的有名称和g个属性,所以在持久化时可以选择持久化名U或是持久化倹{通过</span><font face="Times New Roman">EnumType</font><span style="font-family: 宋体;">来定义,它有两个值如下所C?/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: 宋体;">表示持久化的为枚丄型的名称。默认ؓ(f)</span><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">Q持久化倹{例如以上示例中标注的ؓ(f)</span><font face="Times New Roman">STRING</font><span style="font-family: 宋体;">Q这h久化实体后,数据库中保存的是枚Dcd的名Uͼ如图</span><span style="font-family: 宋体;">所C?/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: 宋体;">Q代码如下:(x)</span></font></p> <p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">         @Enumerated(EnumType.ORDINAL)</font></strong></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         public CustomerType getType() {</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">                   return type;</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: 宋体;">则同h久化的实体后Q数据库保存的结果如?/span><span style="font-family: 宋体;">所C?/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: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">         </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: 宋体;">Q?/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: 宋体;">保存Q虽然从数据库中查询数据旉常直观,能够清楚的看?gu)cd代表意义Q但q样也会(x)带来其他的问题。若此时枚Dcd的定义改变,例如上例中的枚Dcd名称改ؓ(f)Q?/span></font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         public enum CustomerType {</font></p> <p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">                   CUST_COMPETITOR, INVESTOR, PARTNER, VENDER</font></strong></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">COMPETITOR</font><span style="font-family: 宋体;">”的值将不能转化为枚丄?/span><font face="Times New Roman">CustomerType</font><span style="font-family: 宋体;">中的“</span><font face="Times New Roman">CUST_COMPETITOR</font><span style="font-family: 宋体;">”的倹{但若?/span><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">则不?x)带来这U问题。所以徏议?/span><font face="Times New Roman">ORDINAL</font><span style="font-family: 宋体;">cd来持久化枚Dcd?/span></font></p> <p style="margin: 0cm 0cm 0pt 21pt;"><span style="font-family: Wingdings;"><font size="3">l</font><span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">         </span></span><font size="3"><span style="font-family: 宋体;">枚Dcd的定义位|,实体外部</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: 宋体;">枚Dcd定义?/span><font face="Times New Roman">CustomerEO</font><span style="font-family: 宋体;">实体内部Q这是因为只?/span><font face="Times New Roman">CustomerEO</font><span style="font-family: 宋体;">q个实体?x)?/span><font face="Times New Roman">CustomerType</font><span style="font-family: 宋体;">cdQ其他的实体不会(x)使用该类型。该cd与这个实体关pȝ密联pR?/span></font></p> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><font size="3"><span style="font-family: 宋体;">但若此时多个实体公用一个枚丄型时Q则可以枚丄型单独定义,定义在实体的外部。有q样一个枚丄?/span><font face="Times New Roman">BusinessLine</font><span style="font-family: 宋体;">Q它定义在实体外部,代码如下Q?/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;">         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: 宋体;">的枚丄型,代码如下所C?/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;">……</font></span></p> <p style="margin: 0cm 0cm 0pt auto;"><strong><font style="background-color: #e0e0e0;">         private BusinessLine businessLine;</font></strong></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;"> </font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         @Enumerated(EnumType.STRING)</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         public BusinessLine getBusinessLine() {</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">                   return businessLine;</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         }</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;"> </font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         public void setBusinessLine(BusinessLine businessLine) {</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">                   this.businessLine = businessLine;</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">         }</font></p> <p style="margin: 0cm 0cm 0pt auto;"><font style="background-color: #e0e0e0;">}</font></p> <img src ="http://www.aygfsteel.com/sealyu/aggbug/284749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sealyu/" target="_blank">seal</a> 2009-06-30 13:18 <a href="http://www.aygfsteel.com/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 <union-subclass> mapping for xxxxxxxxxxxxxxxxhttp://www.aygfsteel.com/sealyu/archive/2009/02/09/253902.htmlsealsealMon, 09 Feb 2009 06:19:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/02/09/253902.htmlhttp://www.aygfsteel.com/sealyu/comments/253902.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/02/09/253902.html#Feedback1http://www.aygfsteel.com/sealyu/comments/commentRss/253902.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/253902.html State: FAILED
  Reason: javax.persistence.PersistenceException: org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for: com.xxx.xxxx

后来发现问题所在:(x)

l承{略我选择?jin)@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)Q?br /> 同时在父cM讄?jin)ID生成{略为:(x)
@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }
而在q种{略下用unnion-subclass 元素?父类的标识属性生成器不能使用“indentity” Q将{略改ؓ(f) @GeneratedValue(strategy=GenerationType.TABLE)
问题解决?br />

seal 2009-02-09 14:19 发表评论
]]>
EJB/JPAl承详解(?http://www.aygfsteel.com/sealyu/archive/2009/01/05/249911.htmlsealsealMon, 05 Jan 2009 06:18:00 GMThttp://www.aygfsteel.com/sealyu/archive/2009/01/05/249911.htmlhttp://www.aygfsteel.com/sealyu/comments/249911.htmlhttp://www.aygfsteel.com/sealyu/archive/2009/01/05/249911.html#Feedback1http://www.aygfsteel.com/sealyu/comments/commentRss/249911.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/249911.html 每个cd层结构一张表(table per class hierarchy)
每个子类一张表(table per subclass)
每个具体cM张表(table per concrete class)

一、每个类分层l构一张表(table per class hierarchy)
       q种映射方式只需为基cdZ个表卛_。在表中不仅提供基类所有属性对应的字段Q还要提供所有子cd性对应的字段Q此外还需要一个字D는于区分子cȝ具体cd
       要用每个类分层l构一张表(table per class hierarchy) {略Q需要把@javax.persistence.Inheritance 注释?font color="#0000ff">strategy属性设|ؓ(f)InheritanceType.SINGLE_TABLE。除非你要改变子cȝ映射{略Q否?strong>@Inheritance 注释只能攑֜l承层次的基c?/strong>。通过鉴别字段的|持久化引掣可以区分出各个c,q且知道每个cd应那些字Dc(din)?font color="#cc99ff">鉴别字段通过@javax.persistence.DiscriminatorColumn 注释q行定义Q?font color="#0000ff">name 属性定?font color="#cc99ff">鉴别字段的列?/font>Q?/font>discriminatorType 属性定?font color="#cc99ff">鉴别字段的类?/font>Q可选值有QString, Char, IntegerQ,如果鉴别字段的类型ؓ(f)String 或CharQ可以用length 属性定义其长度?font color="#ff0000">@DiscriminatorValue 注释为承关pM?font color="#cc99ff">每个cd义鉴别?/font>Q如果不指定鉴别|默认采用cd
?
    @SuppressWarnings("serial")
    @Entity
    @Table(name="Vehicle_Hierarchy")
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name="Discriminator",
                                         discriminatorType = DiscriminatorType.STRING,
                                         length=30)
    @DiscriminatorValue("Vehicle")
    public class Vehicle implements Serializable{       //基类
    private Long id;
    private Short speed;//速度
    @Id
    @GeneratedValue
    @Column(columnDefinition="integer")//指定使用适配Integer长度的数据类?br />     public Long getId() {
    return id;
    }
    public void setId(Long id) {
    this.id = id;
    }

    @SuppressWarnings("serial")
    @Entity
    @DiscriminatorValue("Car")
    public class Car extends Vehicle{        //Vehicle的子c?/font>
    private String engine;//发动?br />     @Column(nullable=true,length=30)
    public String getEngine() {
    return engine;
    }
    public void setEngine(String engine) {
    this.engine = engine;
        }
    }


     @SuppressWarnings("serial")
     @Entity
     @DiscriminatorValue("Camion")
     public class Camion extends Car{         //Car的子c?/font>
     private String container;//集装?br />      @Column(nullable=true,length=30)
     public String getContainer() {
     return container;
     }
     public void setContainer(String container) {
     this.container = container;
          }
     }
分析:
       ? 以看出,每个子类没有单独的映,在数据库中没有对应的表存在。而只有一个记录所有自w属性和子类所有属性的表,在基cMؓ(f)Vehicle 的时候,Discriminator 字段的值将为Vehicle,在子cMؓ(f)Car 的时候,Discriminator 字段的值将为CarQ子cMؓ(f)Camion 的时候,Discriminator 字段的值将为Camion。那么,如果业务逻辑要求Car 对象的engine 属性不允许为nullQ显然无法在Vehicle_Hierarchy 表中为engine 字段定义not null U束Q可见这U映方式无法保证关pL据模型的数据完整性?/font>

二、每个类分层l构一张表(table per class hierarchy)
       q种映射方式为每个类创徏一个表。在每个cd应的表中只需包含和这个类本n的属性对应的字段Q子cd应的表参照父cd应的?使用每个子类一张表 (table per subclass){略Q需要把@javax.persistence.Inheritance 注释?strong>strategy 属性设|ؓ(f)InheritanceType.JOINED

     @SuppressWarnings("serial")
     @Entity
     @Inheritance(strategy=InheritanceType.JOINED)
     @Table(name="Vehicle")
     public class Vehicle implements Serializable{      //基类
     private Long id;
     private Short speed;//速度
     @Id
     @GeneratedValue
     @Column(columnDefinition="integer")
     public Long getId() {
     return id;
     }
     public void setId(Long id) {
     this.id = id;
     }
     public Short getSpeed() {
     return speed;
     }
     public void setSpeed(Short speed) {
     this.speed = speed;
     }
     }

     @SuppressWarnings("serial")
     @Entity
     @Table(name="Car")
     @PrimaryKeyJoinColumn(name="CarID")     //把主键对应的列名更改为CarID
     public class Car extends Vehicle{                 //Vehicle的子c?/font>
     private String engine;//发动?br />      @Column(nullable=true,length=30)
     public String getEngine() {
     return engine;
     }
     public void setEngine(String engine) {
     this.engine = engine;
     }
     }

     @SuppressWarnings("serial")
     @Entity
     @Table(name="Camion")
     @PrimaryKeyJoinColumn(name="CamionID")     //把主键对应的列名更改为CamionID
     public class Camion extends Car{                    //Car的子c?/font>
     private String container;
     @Column(nullable=true,length=30)
     public String getContainer() {
     return container;
     }
     public void setContainer(String container) {
     this.container = container;
     }
     }
        q种映射方式支持多态关联和多态查询,而且W合关系数据模型的常规设计规则。在q种{略中你可以对子cȝ属性对应的字段定义not null U束。该{略的缺点:(x)
        它的查询性能不如上面介绍的映策略。在q种映射{略下,必须通过表的内连接或左外q接来实现多态查询和多态关联?br /> 选择原则Q子cd性非常多Q需要对子类某些属性对应的字段q行not null U束Q且Ҏ(gu)能要求不是很严格时Q优先选择该策?/font>

三、每个具体类一张表(table per concrete class)
       q种映射方式为每个类创徏一个表。在每个cd应的表中包含和这个类所有属性(包括从超cȝ承的属性)(j)对应的字D?使用每个具体cM张表(table per concrete class){略Q需要把@javax.persistence.Inheritance 注释?strong>strategy 属性设|ؓ(f)InheritanceType.TABLE_PER_CLASS

        注意:一旦用这U策略就意味着你不能用AUTO generator 和IDENTITY generatorQ即主键g能采用数据库自动生成.

     @SuppressWarnings("serial")
     @Entity
     @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
     @Table(name="Vehicle")
     public class Vehicle implements Serializable{            //基类
     private Long id;
     private Short speed;//速度
     @Id
     @Column(columnDefinition="integer")
     public Long getId() {
     return id;
     }
     public void setId(Long id) {
     this.id = id;
     }
     public Short getSpeed() {
     return speed;
     }
     public void setSpeed(Short speed) {
     this.speed = speed;
     }
     }

     @SuppressWarnings("serial")
     @Entity
     @Table(name="Car")
    public class Car extends Vehicle{               //Vehicle的子c?/font>
     private String engine;//发动?br />      @Column(nullable=true,length=30)
     public String getEngine() {
     return engine;
     }
     public void setEngine(String engine) {
     this.engine = engine;
     }
     }

     @SuppressWarnings("serial")
     @Entity
     @Table(name="Camion")
     public class Camion extends Car{              //Car的子c?/font>
     private String container;//集装?br />      @Column(nullable=true,length=30)
     public String getContainer() {
     return container;
     }
     public void setContainer(String container) {
     this.container = container;
     }
     }

注意:在查询时,例如: from Vehicle v
         查询所有VehicleӞ因ؓ(f)他是最l承?wi)中的根Q查询结果会(x)得到所有承于Vehiclecȝ记录
(构造的SQL Where部分Q?strong>where Discriminator in ('Car', 'Camion'))
         delete from Vehicle v
         执行该操作会(x)删除自n对应记录Q还?sh)(x)删除所有承Vehicle的记?因ؓ(f)他是最l承?wi)中的根Q就相当于清除整个表的数?br />
该策略的优点Q?br />                      在这U策略中你可以对子类的属性对应的字段定义not null U束?br /> 该策略的~点Q?br />                      不符合关pL据模型的常规设计规则Q每个表中都存在属于基类的多余的字段。同ӞZ(jin)支持{略的映,持久化管理者需要决定用什么方法,一U方法是? entity 载入或多态关联时Q容器用多ơ查询去实现Q这U方法需要对数据库做几次来往查询Q非常媄(jing)响执行效率。另一U方法是容器通过使用SQLUNIOU 查询来实现这U策略?br /> 选择原则Q?br />                      除非你的现实情况必须使用q种{略Q一般情况下不要选择?/font>

seal 2009-01-05 14:18 发表评论
]]>
EJB3.1计划中的Ҏ(gu)(转)(j)http://www.aygfsteel.com/sealyu/archive/2008/12/22/247720.htmlsealsealMon, 22 Dec 2008 03:20:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/12/22/247720.htmlhttp://www.aygfsteel.com/sealyu/comments/247720.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/12/22/247720.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/247720.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/247720.html 作? Charles Humble译? 张龙 发布? 2008q??0?上午1?4?

Java
主题
Enterprise Application Blocks
标签
EJB,
Java EE

EJB3.1专家l通过JCP发布?u>?/font>博文以提供更多的关于专家l工作情늚信息Q包括对通用EJBlg映射的支持:(x)

“对开发者来说造成挫|的一个共同的源泉是用来解析和查找EJB引用的映信息(如全局JNDI名)(j)的不可移植性。我们不断探索以该信息标准化得应用无需特定于厂商的EJBlg映射可以部|?#8221;

专家l仍处在定义EJB3.1q程的早期阶D,所以上面列出来的特性有可能发生变化。这也是我们通过邮g向专家组提供反馈信息来参与到下一版规范的制定工作中去的绝x?x)?/p>

seal 2008-12-22 11:20 发表评论
]]>
Interceptor 中onFlushDirty()函数执行多次的问题(Hibernate 的一个小BugQ?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/sealyu/archive/2008/05/09/199527.html</guid><wfw:comment>http://www.aygfsteel.com/sealyu/comments/199527.html</wfw:comment><comments>http://www.aygfsteel.com/sealyu/archive/2008/05/09/199527.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/sealyu/comments/commentRss/199527.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/sealyu/services/trackbacks/199527.html</trackback:ping><description><![CDATA[最q在目中遇C个奇怪的问题Q在使用Hibernate拦截器捕获实体变化ƈq行处理Ӟ发现其中的onFlushDirty()函数执行?jin)很多次Q导致进行处理时产生很多重复数据。具体问题如下:(x)<br /> 使用一个类l承Hibernate的EmptyInterceptorcL对程序中的实体变化进行拦截,q在其中的onFlushDirty()函数中对捕获的数据进行处理,产生对应的event数据q保存到数据库中?例如Q?br /> public class EventInterceptor extends EmptyInterceptor {<br /> public boolean onFlushDirty(<br />         Object entity,<br />         Serializable id,<br />         Object[] currentState,<br />         Object[] previousState,<br />         String[] propertyNames,<br />         Type[] types ) throws CallbackException {<br /> <br />         if(isAuditable(entity)){//如果该实体需要被记录Q生成对应的event?br />             //此处生成对应的event?br />         }<br />         return false;<br />     }<br /> <br /> 在程序执行后Q发现对应一条实体的变化生成?jin)多条重复的event记录Q非怸解?br /> 后来google发现Q有Z到q对应的问题Qƈ在Hibernage论坛中提?gu)q个问题Q鉴定ؓ(f)Hibernate的一个小Bug?br /> Q原文地址Qhttp://forum.hibernate.org/viewtopic.php?t=940410&highlight=interceptor+onflushdirtyQ?br /> 解决Ҏ(gu)如下Q?br /> FlushMode改ؓ(f)QFlushMode.COMMIT<br /> 或者也可以提前q行flush()<br /> 都可以解册个问题?br /> <br /> <img src ="http://www.aygfsteel.com/sealyu/aggbug/199527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/sealyu/" target="_blank">seal</a> 2008-05-09 15:59 <a href="http://www.aygfsteel.com/sealyu/archive/2008/05/09/199527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB3.0规范解读Q{载)(j)http://www.aygfsteel.com/sealyu/archive/2008/04/10/192021.htmlsealsealThu, 10 Apr 2008 15:05:00 GMThttp://www.aygfsteel.com/sealyu/archive/2008/04/10/192021.htmlhttp://www.aygfsteel.com/sealyu/comments/192021.htmlhttp://www.aygfsteel.com/sealyu/archive/2008/04/10/192021.html#Feedback0http://www.aygfsteel.com/sealyu/comments/commentRss/192021.htmlhttp://www.aygfsteel.com/sealyu/services/trackbacks/192021.html EJB3.0规范解读
引言  

在本文中对新的规范q行一个概要性的介绍Q包括新增的元数据支持,EJBQL的修改,实体Bean模型讉Kbean上下文的新方法和q行时环境等{。作者还讨论?jin)EJB在未来要作出的调整以?qing)EJB3.0与其他开发规范之间的关系?

开?/strong>

无论如何׃EJB的复杂性之在J2EE架构中的表现一直不是很好。EJB大概是J2EE架构中唯一一个没有兑现其能够单开发ƈ提高生力的l徏? EJB3.0规范正尝试在q方面作出努力以减轻其开发的复杂性。EJB3.0减轻?jin)开发h员进行底层开发的工作量,它取消或最化?jin)很多(以前q些是必? 实现Q回调方法的实现Qƈ且降低了(jin)实体Bean?qing)O/R映射模型的复杂性?

在本文中Q我首先?x)介lEJB3.0中几个主要的? 变。它对进一步深入了(jin)解EJB3.0是非帔R要的。随后,我会(x)从更高的层面来描q已l被提交到EJB3.0规范中的l节Qƈ一个个的讲解新的规范中的改 变:(x)实体Bean,O/R映射模型Q实体关pL型和EJB QL(EJB查询语言){等?

背景

EJB3.0中两个重要的变更分别是:(x)使用?jin)Java5中的E序注释工具和基于Hibernate的O/R映射模型?

Java5中的元数据工?/strong>

Java5Q以前叫J2SE1.5或TigerQ中加入?jin)一U新的程序注释工兗通过q个工具你可以自定义注释标记Q通过q些自定义标记来注释字段、方 法、类{等。这些注释ƈ不会(x)影响E序的语义,但是可以通过工具Q编译时或运行时Q来解释q些标记q生附加的内容Q比如部|描q文Ӟ(j)Q或者强制某些必? 的运行时行ؓ(f)Q比如EJBlg的状态特性)(j)。注释的解析可以通过源文件的解析Q比如编译器或这IDE工具Q或者用Java5中的APIs反射机制。注? 只能被定义在源代码层。由于所有被提交到EJB3.0草案中的注释标记都有一个运行时的RetentionPolicyQ因此会(x)增加cL件占用的存储I? _(d)但这却给容器刉商和工具制造商带来?jin)方ѝ?/div>

Hibernate

目前Hibernate非常受欢q,它是开发源代码的Java O/R映射框架Q目的是把开发h员(sh)J琐的数据持久化~程中解脱出来。它也有一个标准的HQLQHibernate 查询语言Q语aQ你可以在新的EJB QL中看到它的媄(jing)子。Hibernate在处理如数据查询、更新、连接池、事务处理、实体关pd理等斚w非常单?
 
深入研究

现在是时候详l了(jin)解EJB3.0草案?jin)。让我们开始探讨所有EJB中四U企业beanQƈ看看他们在新的规范中是什么样子?

无状态会(x)话bean

在EJB3.0规范中,写一个无状态会(x)话bean(SLSB)只需要一个简单的Java文gq在cd加上@Stateless注释可以了(jin)。这个bean可以扩展javax.ejb.SessionBean接口Q但q些不是必须的?

一个SLSB不再需要home接口Q没有哪cEJB再需要它?jin)。Beancd以实C务接口也可以不实现它。如果没有实CQ何业务接口,业务接口?x)由? 意public的方法生。如果只有几个业务方法会(x)被暴露在业务接口中,q些Ҏ(gu)可以使用@BusinessMethod注释。缺省情况下所有生的接口 都是localQ本圎ͼ(j)接口Q你也可以用@Remote注释来声明这个接口ؓ(f)remoteQ远E)(j)接口?

下面的几行代码就可以定义一个HelloWorldbean?jin)。而在EJB2.1中同L(fng)bean臛_需要两个接口,一个实现类和几个空的实现方法,再加上部|描q符。  

import javax.ejb.*;

@Stateless

@Remote

public class HelloWorldBean {

public String sayHello() {

return "Hello World!!!";

}

}


有状态会(x)话bean

除了(jin)几个SFSB的特别说明之外,有状态会(x)话bean(SFSB)和SLSB一L(fng)Q?

1) 一个SFSB应该有一个方法来初始化自己(在EJB2.1中是通过ejbCreate()来实现的Q。在EJB3.0的规范中q些初始化操作可以通过 自定义方法完成,q把他们暴露在业务接口中。在使用q个bean之前由客L(fng)来调用相应的初始化方法。目前规范组l就是否提供一个注释来标记某个Ҏ(gu)用于 初始化还存在争议?

2) Bean的提供者可以用@Remove注释来标CQ何SFSB的方法,以说明这个方法被调用之后bean的实例将被移除。同P规范l织仍然在讨论是否要有一U机制来处理q种Ҏ(gu)的情况,卛_q个Ҏ(gu)出现异常的情况下bean的实例是否被U除?

下面是对以上问题我个人的观点Q?

1) 是否应该有一个注释来标明一个方法进行初始化呢?我的观点是――应该有Q这样容器就可以在调用其他方法之前至调用一个方法来q行初始化。这不仅可以避免 不必要的错误(׃没有调用初始化方?而且可以使容器更明确的判断是否可以重用SFSB实例。我暂且把这个问题放一放,规范l织只考虑Z个方法提供一 个注释来声明它是一个初始化Ҏ(gu)?

2) 对于W二个问题我的观点也是肯定的。这有利于Bean的提供者合客户端程序对其进行控制。只有一个遗留的问题Q那是一旦调用这个方法失败,是否能移除这个bean 的实例?{案是不能,但是它将?x)在会(x)话l束的时候被U除?

消息驱动Bean

消息驱动Bean是唯一一U必dC个业务接口的Bean。这个接口指出bean支持的是哪一U消息系l。对于以JMS为基的MDB来说Q这个接? 是javax.jms.MessageListener。注意MDB业务接口不是一个真正意义上的业务接口,它只是一个消息接口?

实体Bean

1) 实体Bean使用@Entity注释来标讎ͼ所有实体bean中的属?字段不必使用@Transient注释来标记。实体bean的持久化字段可以通过JavaBean-style机制或者声明ؓ(f)public/protected字段来实现?

2) 实体bean可以使用助手cL描述其状态,但是q些cȝ实例q没有持久化唯一性(persistent identityQ的Ҏ(gu)?卻I唯一标识q个bean的字D늭)Q实际上q些助手cM他们的实体bean实例是紧密结合的Qƈ且这些对象还是以非共享方? 来访问实体对象的?

实体兌

EJB3.0同时支持Bean之间双向? 合单向的兌Q它们可以是一对一、一对多、多对一或者是多对多的兌。然而双向关联的两端q要分ؓ(f)自n端(owning sideQ和Ҏ(gu)端(inverse sideQ不同的端。自w端负责向数据库通告兌的变更。对于多对多的关联自w端必须明确的声明。实际上Ҏ(gu)端通过isInverse=trueq行注释 Q由此自w端׃必说明了(jin)而是由另一D|断出Q。看来上面的描述Q规范组l还能说让EJB变的单了(jin)吗?

O/R映射

EJB3.0中的O/R映射模型也有?jin)重要的改变Q它从原来的abstract-persistence-schema-based变成?jin)现在? Hibernate-inspired模式。尽目前规范组l还在就此进行讨Z是一个明的模型会(x)出现在下一个版本的草案中?

举例来说QO/R映射模型通过beancM的注释来声明。而且此方法还?sh)(x)指出对应的具体表和字段。O/R映射模型提供?jin)一套自有的SQLQ而且除了(jin)? 供一些基本的SQL外还支持某些高层开发的功能。比如,有一个通过@Column注释声明的字DcolumnDefinitionQ那么可以写q样? SQLQcolumnDefinition="BLOB NOT NULL"
 
客户端程序模?/font>

一个EJB客户端可以通过@Inject注释以一U?#8220;注入”的方式获得一个bean的业务接口引用。你也可以用另一个注? @javax.ejb.EJBContext.lookup()来完成上面的操作Q但是规范中没有告诉我们一个普通的Java客户端怎样获得一个Bean 的实例,因ؓ(f)q个普通的Java客户端是q行在一个客L(fng)容器中,它无法访问@javax.ejb.EJBContex对象。现在还有另外一U机制来完成 上面的工作那是使用一个超U上下文环境对象Q@javax.ejb.Context()。但是规范中没有指出该如何在客户端中使用q个对象?

EJB QL

EJB QL可以通过@NamedQuery来注释。这个注释有两个成员属性分别是name和queryString.一旦定义了(jin)q些属性,可以通过 EntityManager.createNamedQuery(name)来指向这个查询。你也可以创Z个标准的JDBC风格的查询ƈ使用 EntityManager.createQuery(ejbqlString)或EntityManager.createNativeQuery (nativeSqlString)(q个Ҏ(gu)用于执行一个本地查?来执行查询?

EJB QL有两个地方可以定义其参数。javax.ejb.Query接口提供?jin)定义参数、指向查询、更新数据等{方法。下面是一个EJBQL指向查询的例子:(x)

.. ..

@NamedQuery(

name="findAllCustomersWithName",

queryString="SELECT c FROM Customer c WHERE c.name LIKE :custName"

)

.. ..

@Inject public EntityManager em;

customers = em.createNamedQuery("findAllCustomersWithName")

.setParameter("custName", "Smith")

.listResults();



下面列出?jin)一些EJB QL的增强特性:(x)

1) 支持扚w更新和删除?

2) 直接支持内连接和外连接。FETCH JOINq行你指出关联的实体QOrder可以指定只查询某个字Dc(din)?

3) 查询语句可以q回一个以上的l果倹{实际上Q你可以q回一个依赖的cL如下面这P(x)  

SELECT new CustomerDetails(c.id, c.status, o.count)

FROM Customer c JOIN c.orders o

WHERE o.count > 100  

4) 支持group by 和having?

5) 支持where子句的嵌套子查询?

在提交的EJB3.0草案中,EJB QL与标准SQL非常的接q。实际上规范中甚至直接支持本地的SQL(像我们上面提到的那?。这一点对某些E序员来说也许有些不是很清楚Q我们将在下面进行更详细的讲解?

多样?/strong>

Ҏ(gu)许可(Method permissions)可以通过@MethodPermissions或@Unchecked注释来声明;同样的,事务属性也可以通过 @TransactionAttribute注释来声明。规范中仍然保留资源引用和资源环境引用。这些一样可以通过注释来声明,但是有一些细微的差别。比 如,上下?context)环境要通过注入工具控制。容器根据bean对外部环境引用自动初始化一个适当的已l声明的实例变量。比如,你可以象下面q样 获得一个数据源QDataSourceQ:(x)  

@Resource(name="myDataSource") //Type is inferred from variable

public DataSource customerDB;

在上面的例子中如果你不指定引用资源的名称(name)那么其中的customerDB?x)被认?f)是默认倹{当所有的引用属性都可得到时Q@Injec注释可以这样写Q  

@Inject public DataSource customerDB;

容器负责在运行时初始化customerDB数据源实例。部|h员必d此之前在容器中定义好q些资源属性?

更好的消息是Q那些以前必L的异常一M复返。你可以声明L的应用程序异常,而不必在再抛出或捕获其他cMCreateException? FinderExceptionq样的异常。容器会(x)抛出装在javax.ejb.EJBException中的pȝU异常或者只在必要时候抛? IllegalArgumentException或IllegalStateException异常?/div>
 
EJB文g处理模式

在我们结束本节之前,让我的快速的览一下容器提供商在EJB处理模式斚w可能的变更。规范中Ҏ(gu)q没有明的表态,但我可以惛_臛_两种模式?

1) 一U办法是首先利用EJB文g生成cM于EJB2.1部v模式的文Ӟ包括必要的接口和部v描述W)(j)然后再用cM于EJB2.1的方式来部vq个EJBl? 件。当?dng)q样产生的部|描q符可能q不标准但是它可以解军_一个容器对EJB2.1和EJB3.0兼容的问题。  

2) 另一U方法是一U类gJSP托放的部|模式。你可以把一个EJB文g攑ֈ一个预先定义的目录下,然后容器?x)识别这个EJBq处理它Q然后部|ƈ使之可以 使用。这U方法可以徏立于上面那种Ҏ(gu)之上Q在支持反复部v时有很大的帮助。考虑到部|的单性也是EJB3.0规范的目的之一Q我真诚的希望在下一个草 案出来时能够定一个模?臛_能有一个非正式??

你有什么想法?

EJB3.0规范的制定正在有序的q? 行,Z(jin)使EJB的开发变得更加容易,EJB规范l织作出的努力是有目q的。就像他们说的那P一切对?x)变得简单,但做到这一点ƈ不容易。目前已l定? ?0个注释标?q有几个在下一个草案中发布)Q每一个都有自q~省规则和其他的操作。当?dng)我真的不希望EJB3.0变成EJB2.1的一个翻? "EJB 3.0 = EJB 2.1 for dummies"Q希望这个等式不要成立)(j)。最后,我还是忍不住要提一些我自己的观点:(x)

1) 首先Q规范确实反复部v变得Ҏ(gu)?jin),q且有一个简单的模式来访问运行时环境。我q是觉得home接口应该攑ּ?

2) 在早期的EJB规范中,实体bean用于映射一个持久化存储。理Z(也许只是理论?可能需要把实体bean映射C个遗留的EIS (enterprise information system)pȝ中。出于将来扩展的考虑q样作是有好处的Qƈ且可以更多的业务数据模型采用实体bean。也因此其伴随的复杂性得实体bean不被 看好。在本次提交的草案中Q一个实体bean只是一个数据库的映。ƈ且是Z非抽象持久化模式和简单的数据讉K模式的更加简单开发?

3) 我对模型变更持保留态度Q我认ؓ(f)在EJB中包含SQL脚本片断q不是个好注意。一些开发h员完全反对包含某?#8220;SQL片段QSQLnessQ?#8221;Q比? @Table ? @Column注释Q。我的观Ҏ(gu)q些SQLness是好的,据此我们可以清楚的知道我们到底要数据库作些什么。但是某些SQLD|看来q不是很好,比如 columnDefinition="BLOB NOT NULL"Q这使得EJB代码和SQL之间的耦合太过紧密?jin)?

4) 管对于本地SQL的支持看似很׃hQ其实在EJB代码中嵌入SQL是一个非常糟p的L。当?dng)有些办法可以避免在EJB中硬~码SQLQ但是这应该在规范中说明Q而不能是某些开发h员自己定义的模式?

5) 假设@Table注释只用于类。在q行旉过@Table注释的name属性定义的表名U将必须对应一个实际的数据库表。规范对此应该给予清楚的说明和一致的模式?

6) 规范q需要更清楚的说明客L(fng)~程模型Q尤其是普通java客户端。规范中所有的参考都假设或者隐含的使用EJB客户端。而且规范中对客户端的向后兼容斚w也没有给出明的说法?

7) Transient注释应该重新命名以避免和已有的transient关键字发生冲H。事实上Q在q一点上我们更乐于稍微的背离一? configuration-by-exception原则q且定义一个@Persistent注释来明的定义持久化字Dc(din)@Persistent注释 可以仅仅是一个标记注释或者它可以有几个属性来兌O/R映射注释?

与其他规范的兌

目前可能影响到EJB3.0的JSR有JSR175Qjava语言元数据工P(j)和JSR181QJava Web服务元数据)(j)

JSR175已经初步完成q且不会(x)和EJB3.0有太大的冲突Q但是JSR181与EJB3.0有两个关联的地方Q?

1) Web service接口QEJB规范?yu)采用一U机刉应JSR181以便可以把一个bean实现Z个Web serviceq告诉Web service如何被客L(fng)调用?

2) JSR 181计划采用不同的机制来处理安全问题。在早期的规范中EJB使用一个一致的机制QMethodPermissionsQ,但是JSR 181计划使用一个稍微不同的方式QSecurityRoles和SecurityIdentity注释Q。同L(fng)RunAs注释的定义也存在q些许差 别。这一问题q在解决中最l会(x)在J2EE层的规范中维持其一致性?

在J2EE 1.5中的一些开发规范可能与EJB3.0有关联。除?jin)上面说到的几个兌之外现在没有其他的开发规范与EJB3.0有冲H?

l束?

在EJB的开发变得简单高效之前,我们q有很长一D\要走。规范组l在降低EJB的开发难度方面v?jin)个好头。O/R映射模型的提议还处在早期阶段Q规范组l正在完善它。我希望它不要太复杂也不要与SQLq分的耦合?/div>

seal 2008-04-10 23:05 发表评论
]]> վ֩ģ壺 ɽ| ͻȪ| ٰ| ɽ| ԭ| ƽ| | ˰| Դ| | | | | | | ƾ| Ԫ| | Ҧ| Ϫ| Т| ͷ| ƽ| ף| | ɿ| ɽ| | | ӳ| | ʯ| ײ| | | Ͱ| | μԴ| ׳| | |