全面研读EJB 2.0(2)
· EJB 2.0 的 CMP 模型
在 EJB 2.0 中,CMP 实体 bean 和持久性治理器之间的新合约,使您能够在实体 bean 中定义更复杂的、可移植性更强的关系,包括 bean 与 bean 之间、bean 与从属对象之间、甚至从属对象与从属对象之间的关系。
持久性治理器是新加入到 Enterprise JavaBeans 部署过程中的。容器厂商,或专长于特定数据库的持久性的厂商,将能提供这种持久性治理器。其思路是将用于治理 bean 关系的机制从容器中分离出来,容器只负责治理安全、事务和资源。这种职责上的分离使不同的持久性治理器能够与不同的容器一起工作。它也使实体 bean 在不同 EJB 厂商之间以及在各种持久性治理器之间具有更强的可移植性。
假如您使用或学习过 Thought Inc. 生产的,能自动为 EJB 1.1 容器生成 BMP(bean 治理的持久性)bean 的产品 CocoBase,则您对持久性治理器工具如何工作就已经比较熟悉了。CocoBase 根据 bean 部署者提供的,从对象到关系的映射信息,为 BMP bean 生成全部数据库访问逻辑。在 EJB 2.0 中,持久性治理器能够根据部署描述符、bean 的抽象持久性方案和部署者完成的工作所提供的信息,生成 CMP 实体到关系数据库的映射。但是,持久性治理器并不局限于关系数据库。也可以为对象数据库以及遗留的系统和 ERP 系统(如 SAP)开发持久性治理器。
为了将持久性治理器从容器中分离出来,必须定义 bean 与持久性治理器之间的合约。这个合约在新的抽象持久性方案中表现出来。此方案是通过部署描述符中一组新的 XML 元素和 CMP 实体 bean 中的一组代码习语定义的。在 EJB 2.0 中,CMP bean 类被声明为抽象类,它的持久性字段和关系字段是使用抽象的读方法和写方法来访问的,而这两种方法的方法特征则映射为 XML 部署描述符中的特定元素。
在部署该 bean 时,您将使用持久性治理器工具,根据 XML 部署描述符和 bean 类,来具体实现此抽象 bean 类及其从属对象类。具体实现将包括数据访问代码,此代码将在运行时将 bean 的状态实际读出和写到数据库中。在运行时,容器使用由持久性治理器工具生成的子类,而不使用 bean 提供者定义的抽象类。
bean 类的继续层次结构
为了使讨论更充实,这里提供一个 CMP 实体的示例,它更具体地说明了抽象持久性方案是如何工作的。
EJB 2.0 中的一个示例 CMP 实体
在 EJB 2.0 中,容器治理的实体 bean 被定义为抽象的,而且它的持久性字段并不在 bean 类中直接定义。作为替代,开发了一种抽象的持久性方案,从而答应 bean 提供者间接地声明持久性字段和 bean 关系。下面是 Employee bean 的一个示例,它使用了新的抽象持久性方案。请注重,该 bean 类中未声明任何持久性字段。
public abstract EmployeeBean implements
javax.ejb.EntityBean {
. // 实例字段
EntityContext ejbContext;
// 容器治理的持久性字段
public abstract void setIdentity(int
identity);
public abstract int getIdentity();
public abstract void setFirstName(String
firstName);
public abstract String getFirstName();
public abstract void setLastName(String
lastName);
public abstract String getLastName();
// 容器治理的关系字段
public abstract void
setContactInfo(ContactInfo info);
public abstract ContactInfo
getContactInfo();
...
}
在此 bean 的 XML 部署描述符中,抽象的持久性方案声明容器治理的各个字段和各种关系。
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>EmployeeEJB</ejb-name>
...
<persistence-type>Container</persistence-type>
...
<cmp-field><field-name>identity</field-name></cmp-field>
<cmp-field><field-name>firstName</field-name></cmp-field>
<cmp-field><field-name>lastName</field-name></cmp-field>