快捷搜索:

使用 EJB 3.0 Java Persistence API 设计企业应用程序

本文将先容 Java™ Platform, Enterprise Edition (Java EE 5) 的一种设计措施,它使用了 Enterprise JavaBeans™ (EJB) 3.0 新的 Java Persistence API (JPA)。JPA 供给了一种标准的工具关系映射办理规划,该办理规划避免了依附第三方框架(如 Hibernate)。您将看到示例利用法度榜样的具体内容,此中验证了本措施并说明关键设计抉择。

等候已久的下一版本 Java EE 5 即将宣布(拜见 参考资料 得到规范和预览版的链接)。Java EE 5 许多新功能都包孕颠末修补的 EJB 架构,其凸起特点之一是 JPA。因为具有容器内和容器外持久性选项,JPA 为 J2EE 架构师带来一系列全新设计选择。本文将着重先容容器内利用法度榜样的设计,此类利用法度榜样依附 EJB 容器供给企业办事,如事务处置惩罚和安然性。

我将应用您认识的 PetStore 利用法度榜样进行测试,以证实 JPA 的功能以及它若何向传统 J2EE 设计模式提议寻衅。本利用法度榜样对照啰唆,以是不供给详尽的实现细节。我将用代码摘录对设计留意事变进行阐明(完备开放源码的连接请拜见 下载 )。本文假设您认识 EJB 3.0 基础观点和工具关系(OR)映射基础观点。(若需懂得这两个主题的更多信息,请参阅 参考资料 )。

设计概述

示例 PetStore 利用法度榜样是基于 Web 的电子买卖营业利用法度榜样,它实现以下用例:

浏览产品

查找产品

掩护账户

掩护购物车

创建订单

本利用法度榜样被设计为具有三个主要逻辑层的多层 Java EE 利用法度榜样:

表示层(并非本文的重点)应用 Struts 框架。

办事层是一种简单的办事 facade,将所有事情委托给其协作者。办事层的目的是分离办事供应与办事实现。

数据造访层是一系列作为无状态会话 bean 实现的粗粒度 Data Access Objects (DAO)(拜见 参考资料)。出于持久性的必要,它们都依附 Java 持久性实体治理器。

利用法度榜样域模型由 EJB 3.0 实体 bean 表示并用于层间的通信。当域工具脱离数据造访层时,它与实体治理器离开。当从新进入数据造访层时,它必要从新连接到实体治理器。

注释彷佛是 Java 5 的一个广泛采纳的特点,JPA 也不例外。注释可用于指定 OR 映射 —— 在 dW 文档和教程中您常常可以看到 —— 而 PetStore 利用法度榜样出于相同目的应用它们。然而值得一提的是您还能经由过程映射文件的要领指定 OR 映射。本文稍后的 OR 映射 一节将探究并对照这两种可选要领。

我在 Jboss 利用办事器中开拓并支配 PetStore 利用法度榜样(拜见 参考资料)。我应用商用数据库完成大年夜多半开拓事情并将利用法度榜样后端移植到 PostgreSQL 数据库(OR 映射 一节包孕了关于应用 JPA 时您应该懂得的数据库迁移的潜在影响的评论争论)。

本案例阐发的目的之一是相符设计标准,容许高度可测试的实现。如 测试 一节所见,您能够应用一系列测试技巧来测试 PetStore 利用法度榜样。

PetStore 利用法度榜样充分使用了这一事实:它是规则的 Web 利用法度榜样。主要优点是所有层能够运行在相同的 JVM 中,免除了组件分发的必要。本文的 远程处置惩罚 一节简要先容了为利用法度榜样添加远程处置惩罚功能的措施。

办事层

办事层被设计为办事 facade。它由 PetStoreService 这一无状态会话 bean 实现。Bean 要完全寄托其协作者来供给 Web 办事。

由于简化的 PetStore 要求被限制于从数据库检索数据并把数据存储于数据库,惟一的协作者便是 DAO。真正的利用法度榜样能够调用 Web 办事,经由过程 RMI/IIOP 或资本适配器造访其他利用法度榜样,并天生电子邮件消息等。所有此类型的功能都必要其他协作者支持。

可经由过程 @EJB 或 @Resource 注释注入协作者(如清单 1 所示)或经由过程 @PostConstruct 措施注入协作者(如清单 2 所示):

清单 1. 应用 @EJB 注入协作者

@EJB(beanName = "AccountDao")

AccountDao accountDao;

清单 2. 应用 @PostConstruct 注入协作者

MessageSource messageSource;

@PostConstruct

public void init() {

messageSource = new MessageSourceImpl("exceptions");

}

选择 bean 实现类的测试策略的主要身分是类完全依附协作者来供给办事。这意味着类和协作者的交互感化必要被验证。正如您在 测试 一节看到的,仿照工具措施完全满意该目标。

数据造访层

数据造访层被设计为一系列粗粒度的 DAO。DAO 被实现为无状态会话 bean,一个 bean 对应一个逻辑域:AccountDao、OrderDao 和 ProductDao。

每个 bean 都要把实体治理器注入到此中:

@PersistenceContext(unitName = "manager1")

protected EntityManager em;

这是利用法度榜样中 持久性调用类(persistence-aware) 最多的层。它广泛应用全新的 Enterprise JavaBeans Query Language(EJB QL)(拜见 参考资料)。所有持久性相关的行动都在该层发生,例如:

profile = (UserProfile) em.createQuery(

"from UserProfile up where up.login = :login").setParameter(

"login", login).getSingleResult();

下面是另一个例子:

em.persist(account);

事实上这些类是持久性调用类(persistence-aware),必要一种容器内测试策略,这将在 测试 一节进行描述。

域模型

您可以把 JPA 看作是众所周知的透明持久性技巧(如 JDO 和 Hibernate)的承袭者。只管透明持久性可看作一个附加(add-on)办事,可被利用到轻忽持久性的 Plain Old Java Objects (POJO)中,但 JPA 照样对域工具施加了少量限定。

首先,您平日要具有一个映射到对应数据库表主键的(代理)工具标识符:

@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "AccountSeq")

@Column(name = "account_sysid")

public Integer getAccountId() {

return this.accountId;

}

其次,在联机事务历程(OLTP)情况中,必要一个 version 字段或 JavaBean 属性以进行乐不雅并发节制:

@Column(name = "row_version")

@Version

public int getVersion() {

return version;

}

终极,假如您选择应用注释要领的映射,映射注释将散播在代码周围。

另一种限定源自于这样一个事实:域工具可以经由过程由实体治理器所治理的域工具所在的层造访,也可以经由过程分离它的所有其他层造访。此外,工具可能是新的或已删除的。一样平常环境下,工具的行径取决于其持久性状态。例如,假设在实体治理器中履行以下这行代码:

int size = attachedProduct.getItems().size();

项聚拢应用给定产品的项添补,size 变量的值大年夜于 0。假如应用默认懒加载(lazy)设置设置设备摆设摆设的一对多关联,并在表示层中履行同一行代码,size 变量的值为 0。 换句话说,在实体治理器之外(在实体治理器内也不要紧)无法把 非活动(lazy) 工具与 活动(eager) 工具区分开。办理此问题的措施是强制履行项目规范和约定。

在域工具中,您可以把相同的推理利用到营业措施。无论是否在实体治理器中,它们都应该筹备好在任何层中调用。这便是把域工具中的营业措施数量限定为需要的起码数量的来由。

虽然有上述各类环境,域工具依然保留许多 POJO 特点。这意味着您可以应用 plain old Java test (POJT) 对营业措施进行测试,POJT 这一术语引自 Expert One-on-One J2EE Development without EJB 一书(拜见 参考资料。)

OR 映射

OR 映射是环抱 JPA 设计的利用法度榜样的紧张元素。它直接影响实体治理器添补域工具的要领。是以,变化映射能够在表示层觉察到。变化获取类型或级联类型可能将孕育发生异常晦气的影响。

正如前面所述,有两种定义映射的措施:元数据(注释)和映射文件。只管我们高度提倡采纳元数据的措施,但您应该也留意到了它所带来的不便。从本色上讲,此措施扳连利用法度榜样的两个逻辑层:域模型和映射信息。由于这两个层是分散的,以是这两个层必要应用不合技巧进行零丁测试。元数据措施本身不会影响层的可测试性。更确切的说,元数据措施使这两个层似乎只是一个层,因为受一系列身分的影响,这可能会引起问题。

影响映射措施选择的一个身分是项目小组布局。在只有少数开拓职员介入的小型项目中,表的数量很少(一样平常说来少于 100 个表)而且没有专职的映射职员,由于平日应用注释会加倍快速,以是把注释措施看作定义映射大概是最佳选择。对付拥有专职映射职员或映射小组的中型和大年夜型项目来讲,应用映射文件的措施才是更好的选择。该措施可以低落资本争用并使开拓历程具有另一种自由度。基于元数据的映射措施证明是 PetStore 利用法度榜样加倍节省光阴的措施。

OR 映射层的目的是使另外利用法度榜样免受底层数据库变化的影响。当把 PetStore 利用法度榜样后端迁移到 PostgreSQL 时,无需对映射层作出任何变化。这可能要归结于这一事实:原始数据库和 PostgreSQL 这两者均支持序列,是以主键天生策略维持齐全。一样平常环境下,您应该对与工具 ID 处置惩罚相关的映射区域进行重写。

对映射的周全测试覆盖极为紧张。必须覆盖所有关系映射以确保对获取行径和过渡持久性进行测试。您能够使用容器外应用的 JPA 来履行该义务(将鄙人一节进行具体先容)。

测试

办事层设计的关键要素是,关注与底层的协作以供给哀求的办事。这必要斟酌到应用动态仿照工具的靠得住测试策略。我应用 EasyMock 框架(拜见 参考资料)来实现测试措施。

DAO 层具有强大年夜的数据库内聚力。这便是靠得住测试必要某类容器内策略和数据库造访的缘故原由。只管这对付远程 EJB 很轻易,照样必要斟酌得当本地 bean 的故意义的措施。此处令人困扰的身分是:

必要容器内测试 facade

域工具长短继续的,以是整个验证必要发生在容器内。

JBoss Embeddable EJB3 容器(拜见 参考资料) (撰写这篇文章时尚处于测试版阶段)被证明是更适当的选择。由于能够从单元测试启动 JBoss Embeddable EJB3 容器,这样所有代码都运行在同一 JVM 中。应用可嵌入容器的容器内测试可实现它的目标,但历程对照迟钝,由于容器启动光阴就必要大年夜概 30 秒。这种问题可能是由较早的产品状态造成的,可经由过程合理的设置设置设备摆设摆设改进。

我采纳 POJT 对域模型类的营业措施进行测试。不必要其他测试技巧,况且其他测试技巧不得当这些类。

OR 映射是一个必要穷举测试覆盖的主要层。该层对数据库异常敏感,以是该层不能利用仿照工具或 POJT 技巧。然则,您可以使用 JPA 的容器外功能。我就应用这种策略来测试 PetStore 或 OR 映射层。

您必要切记测试中的测试关联和过渡持久性行径的紧张性。这样您才能赶早留意到获取类型的变化或级联类型值的变化,并采取适当的步伐。

远程处置惩罚

PetStore 利用法度榜样设计的关键特点是它的本地特点。使利用法度榜样的所有逻辑层运行在同一 JVM 中,这种措施具有很多优点。有关该主题的具体评论争论,请参阅 Expert One-on-One J2EE Development without EJB(拜见 参考资料)。

不过,该当阐明的是:经由过程远程处置惩罚 facade,您可以轻松向利用法度榜样添加远程处置惩罚功能。远程处置惩罚 facade(而不是我在前面描述的办事 facade)公开了一个远程界面,它具有两个职责:进行域模型和顺序数据传输工具(DTO)(拜见 参考资料)之间的互相转换和在办事 facade 上调用适当的措施。

应用远程无状态会话 bean 能够实现本利用法度榜样。独一障碍是创建其他 DTO 层和进行它们与域模型之间互相转换。然而您必要它来确保实现整齐的界面以及与远程客户机的疏松耦合。

停止语

EJB 3.0 和 JPA 毫无疑问将是 Java EE 5 的主要卖点。在某些领域中,它们给正常的 Java 社区带来竞争上风,并使 Java 在其他领域与竞争对手不分别足。(弗成否认的是,今朝某些领域尚不存在基于标准的措施。)

以前数年来,Spring Framework(拜见 参考资料)不停是 EJB 在企业领域的主要竞争对手。EJB 3.0 规范办理了很多匆匆进 Spring 兴起的问题。跟着它的呈现,EJB 3.0 毫无疑问比 Spring 供给了更好的开拓体验 -- 最惹人注目的上风是它不必要设置设置设备摆设摆设文件。

JPA 供给一种标准的 OR 映射办理规划,该办理规划完全集成到 EJB 3.0 兼容的容器中。JPA 的前辈将会继承稳定成长,然则营业利用法度榜样中的 raw 应用将可能会削减。实现 JPA 兼容的实体治理器彷佛很可能是此类技巧的成长偏向。

在撰写本文时,EJB 3.0 规范还处在建议的终极草案(Proposed Final Draft)阶段(拜见 参考资料)。以下是一些未办理的问题以及与 JPA 相关的预实现:

• 当前形式的 JPA 规范没有定义只读实体 bean。这让人利诱,由于兼容 EJB 2.1 规范的实体 bean 支持这种特点。Spring 框架也支持只读事务。

• 可插入的持久性供给者观点仍处于未交付的阶段。

• 标准乐不雅并发非常 -- OptimisticLockException -- 首次呈现在 EJB 3.0 Proposed Final Draft 中。在持久性供给者履行它曩昔 ,您还必要应用特定于供给者的非常,如 Hibernate 的 StaleObjectStateException,来检测乐不雅并发问题。暂时,这种环境限定您的实现只能采纳特定的持久性供给者。

Java EE 系列规范的较大年夜问题与 JPA 没有任何关系。Java EE 系列规范的问题涉及到 Web 和 EJB 容器之间的集成。Spring 在此领域仍旧具有主要竞争上风。JBoss 的 Seam 项目(拜见 参考资料)考试测验应用自定义的措施来办理这一问题。Caucho Resin 利用办事器(拜见 参考资料)试图扩展容器界限并支持在 Web 容器中应用 @EJB 注释。我们盼望 Java EE 5.1 将办理层集成的问题,为我们供给一个周全而标准的依附性注入措施。

下载

描述

名字

大年夜小

下载措施

PetStore

j-ejb3jpapetstore.zip

149KB

HTTP

关于下载措施的信息

Get Adobe® Reader®

参考资料

进修

您可以参阅本文在 developerWorks 举世站点上的 英文原文

JSR 220: Enterprise JavaBeans 3.0EJB 3.0 Proposed Final Draft:在 Java Community Process 网站上查看最新的 EJB 3.0 及 JPA 规范。

Rod Johnson 和 Juergen Hoeller 所著的 Expert One-on-One J2EE Development without EJB(Wrox,2004 年):懂得 EJB 替代措施和 Spring Framework。

"EJB 倡导者: EJB 2.x 逾期了吗? (Geoff Hambrick,developerWorks,2006 年 2 月):这篇文章探究了 EJB 3.0 规范的一些新特点(包括 JPA)。

JBoss EJB 3.0 Project:涉猎 JBoss 的 EJB 3.0 实现。

Hibernate:Hibernate 是一种开放源码透明持久性框架。

Data Access Object:涉猎 Data Access Object (DAO) 设计模式。

Core J2EE Patterns - Transfer Object:涉猎 Transfer Object 设计模式。

Spring Framework:Spring 是 EJB 的主要竞争对手。

JBoss Seam:JBoss Seam 是 Java EE 5 的利用法度榜样框架。

Resin:开放源码利用办事器中的 Resin。

Java 技巧专区 稀有百篇关于 Java 编程各个方面的文章。

得到产品和技巧

Java Platform, Enterprise Edition (Java EE) 5:下载预览版。

EasyMock:应用 EasyMock 库对您的代码和动态仿照工具措施进行测试。

JBoss Embeddable EJB3:在“容器外”测试容器内代码。

关于作者

Borys Burnayev 是一名具有跨越 12 年从业履历的软件开拓职员,以前 5 年中,他从事 Java 及相关技巧的事情,近来开始专注于 J2EE 设计问题与工具关系技巧。Borys 拥有利用数学的硕士学位。他还拥有 Sun Certified Architect 技巧认证和 Sun、Oracle 、IBM 多家公司的其他技巧认证。

您可能还会对下面的文章感兴趣: