域模型
您可以把JPA看作是众所周知的透明持久性技术(如JDO和Hibernate)的继承者。尽管透明持久性可看作一个附加(add-on)服务,可被应用到忽略持久性的 Plain Old Java Objects (POJO)中,但JPA还是对域对象施加了少量限制。
首先,您通常要具有一个映射到对应数据库表主键的(代理)对象标识符:
1 @Id
2 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = “AccountSeq”)
3 @Column(name = “account_sysid”)
4 public Integer getAccountId() {
5 return this.accountId;
6 }
其次,在联机事务过程(OLTP)环境中,需要一个version字段或JavaBean属性以进行乐观并发控制:
1 @Column(name = “row_version”)
2 @Version
3 public int getVersion() {
4 return version;
5 }
最终,如果您选择使用注释方式的映射,映射注释将分布在代码周围。
另一种限制源自于这样一个事实:域对象可以通过由实体管理器所管理的域对象所在的层访问,也可以通过分离它的所有其他层访问。此外,对象可能是新的或已删除的。一般情况下,对象的行为取决于其持久性状态。例如,假设在实体管理器中执行以下这行代码:
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中,这种方法具有很多优点。有关该主题的详细讨论。
不过,应当说明的是:通过远程处理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将解决层集成的问题,为我们提供一个全面而标准的依赖性注入方法。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
相关推荐
-
Spring针对Java 8升级
Java 8刚刚在几周前发布。后来Spring Framework项目负责人发表了题为《企业项目中的Java 8》的文章。文中,指出那些著名的Java EE应用服务器如何不允许轻松升级。
-
你应该远离的六个Java特性
近日,Tarnovski撰文谈到了普通开发者应该尽量避免使用的6个Java特性,这些特性常见于各种框架或库当中,使用这些特性也许会给你所开发的应用带来灾难。
-
从测试数据来看Node.js和Java EE的性能区别
本文是通过从CouchDB上读取JSON数据来比较Node.js和Java EE之间的性能的。究竟谁的性能更好些?
-
Spring 烂!差!
有些人可能对Spring的第一印象不太好,它真的很烂,很差吗,也许这只是你的一种偏见,它也有是自己的优点的。