当前页面: 开发资料首页 → JSP 专题 → 前进:从EJB 2.1到EJB 3.0
摘要: 前进:从EJB 2.1到EJB 3.0
另外,也要注意,通过@Local注释,上面的EJB 3.0bean类用一个本地业务接口(POJI)取代了EJB 2.1中的组件与主接口。
迁移EJB会话bean客户端
一个EJB 2.1会话bean的客户端通过使用JNDI名可取得一个会话bean对象,如下所示的客户端使用了BookCatalogLocalHome的JNDI名取得一个本地主对象,接着调用了create()方法,随后,客户端用getEdition(String)业务方法输出特定标题的版本值。
import javax.naming.InitialContext;
public class BookCatalogClient
{
public static void main(String[] argv)
{
try{
InitialContext ctx=new InitialContext();
Object objref=ctx.lookup("BookCatalogLocalHome");
BookCatalogLocalHome catalogLocalHome = (BookCatalogLocalHome)objref;
BookCatalogLocal catalogLocal = (BookCatalogLocal) catalogLocalHome.
create();
String title="Java and XML";
String edition = catalogLocal.getEdition(title);
System.out.println("标题的版本:" + title + " " + edition);
}
catch(Exception e){}
}
}
在EJB 3.0中,可通过依赖性注入,来获取一个对会话bean对象的引用,这通常由@Inject、@Resource、@EJB注释来实现。如下所示的EJB 3.0会话bean客户端使用了@Inject注释注入到BookCatalogBean类中,仍可由getEdition(String)业务方法来获取标题的版本值。
public class BookCatalogClient
{
@Inject BookCatalogBean;
BookCatalogBean catalogBean;
String title="Java and XML";
String edition=catalogBean.getEdition(edition);
System.out.println("标题版本:" + title + " " + edition);
}
迁移实体bean
本节讲述如何迁移EJB 2.1的实体bean到EJB 3.0。一个EJB 2.1实体bean实现了EntityBean接口,其由getter和setter CMP字段方法、getter和setter CMR字段方法、回调方法及ejbCreate/ejbPostCreate方法组成。示例实体bean(见例1)--BookCatalogBean.java,由CMP字段标题、作者、发行者和CMR字段版本组成。
例1:BookCatalogBean.java
import javax.ejb.EntityBean;
import javax.ejb.EntityContext;
public class BookCatalogBean implements EntityBean
{
private EntityContext ctx;
public abstract void setTitle();
public abstract String getTitle();
public abstract void setAuthor();
public abstract String getAuthor();
public abstract void setPublisher();
public abstract String getPublisher();
public abstract void setEditions(java.util.Collection editions);
public abstract java.util.Collection getEditions();
public String ejbCreate(String title)
{
setTitle(title);
return null;
}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbLoad() {}
public void ejbStore() {}
public void setEntityContext(EntityContext ctx)
{
this.ctx=ctx;
}
public void unsetEntityContext()
{
ctx = null;
}
}
而这个EJB 2.1实体bean的ejb-jar.xml部署描述符(见例2)文件,指定了EJB类、接口、CMP字段、EJB QL查询和CMR关系。BookCatalogBean实体Bean定义了一个查找方法findByTitle()、一个CMR字段及版本。
例2:ejb-jar.xml部署描述符
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC
"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>BookCatalog</ejb-name>
<local-home>BookCatalogLocalHome</local-home>
<local>BookCatalogLocal</local>
<ejb-class>BookCatalogBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>String</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>BookCatalog</abstract-schema-name>
<cmp-field>
<field-name>title</field-name>
</cmp-field>
<cmp-field>
<field-name>author</field-name>
</cmp-field>
<cmp-field>
<field-name>publisher</field-name>
</cmp-field>
<query>
<query-method>
<method-name>findByTitle</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>
<![CDATA[SELECT DISTINCT OBJECT(obj) FROM BookCatalog obj WHERE obj.title = ?1 ]]>
</ejb-ql>
</query>
</entity>
</enterprise-beans>
<relationships>
<ejb-relation>
<ejb-relation-name>BookCatalog-Editions</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>
BookCatalog-Has-Editions
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>BookCatalog</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>editions</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>
Editions-Belong-To-BookCatalog
</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<cascade-delete />
<relationship-role-source>
<ejb-name>Edition</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
</ejb-relation>
</relationships>
</ejb-jar>
相比之下,对应于EJB 2.1实体bean类的EJB 3.0实体Bean类是一个纯旧式Java对象(POJO),并且非常简单(请看例3)。此bean类的EJB 3.0版本使用了元数据注释@Entity,而EJB 2.1部署描述符ejb-jar.xml文件中用元素符指定的查找方法,在EJB 3.0 Bean类中,则使用@NamedQueries和@NamedQuery注释来指定;ejb-jar.xml文件中用元素符指定的CMR关系,在EJB 3.0 Bean类中,则用元数据注释来指定;另外,主要的关键字段通过@Id注释来指定。表1中列出了一些EJB 3.0的元数据注释。
例3:BookCatalogBean.java
import javax.persistence.Entity;
import javax.persistence.NamedQuery;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.OneToMany;
@Entity
@NamedQuery(name="findByTitle", queryString =
"SELECT DISTINCT OBJECT(obj) FROM BookCatalog obj WHERE obj.title = ?1")
public class BookCatalogBean
{
public BookCatalogBean(){}
public BookCatalogBean(String title)
{
this.title=title;
}
private String title;
private String author;
private String publisher;
@Id
@Column(name="title", primaryKey="true")
public String getTitle(){return title;}
public void setTitle(){this.title=title;}
public void setAuthor(String author){this.author=author;}
public String getAuthor(){return author;}
public void setPublisher(String publisher)
{
this.publisher=publisher;
}
public String getPublisher(){return publisher;}
private java.util.Collection<Edition>editions;
@OneToMany
public void setEditions(java.util.Collection editions)
{
this.editions=editions;
}
public java.util.Collection getEditions(){return editions;}
}
表1:EJB 3.0常用元数据注释
<table cellSpacing=0 cellPadding=0 width="90%" align=center border=1>
迁移EJB实体Bean客户端
你可在实体bean主接口或本地主接口中使用create()方法,来创建一个EJB 2.1实体bean主对象或本地主对象。通常,一个EJB 2.1实体bean的客户端可通过JNDI查找来获取一个实体bean的本地或远程对象。下面有一段示例代码,其创建了一个EJB 2.1实体bean的本地主对象。
InitialContext ctx=new InitialContext();
Object objref=ctx.lookup("BookCatalogLocalHome");
BookCatalogLocalHome catalogLocalHome = (BookCatalogLocalHome)objref;
在上面的代码段中,BookCatalogLocalHome是BookCatalogBean实体bean的JNDI名。
在得到一个引用之后,EJB 2.1的客户端通过create()方法创建了一个本地对象。
BookCatalogLocal catalogLocal = (BookCatalogLocal)
catalogLocalHome.create(title);
在EJB 2.1中,可通过查找方法,从一个本地主对象中取得一个本地或远程对象。例如,你可像如下所示通过findByPrimaryKey方法取得一个本地对象。
BookCatalogLocal catalogLocal = (BookCatalogLocal)
catalogLocalHome.findByPrimaryKey(title);
另外在EJB 2.1中,可使用remove()方法移除一个实体bean的实例:
catalogLocal.remove();
EJB 3.0通过javax.persistence.EntityManager类实现了持久性、查找和移除。表2列出了EntityManager类中用于取代EJB 2.1方法的一些常用方法。
表2:EntityManager类方法
<table cellSpacing=0 cellPadding=0 width="90%" align=center border=1>