|
JPA在JavaEE中很大程度上取代的是前辈Entity Bean(实体Bean)的江湖地位,而大多数部署的Entity Bean为CMP。我就自己在日常工作中对于CMP进行升迁积累的一些经验进行一些总结。
首先,我们要解读Java EE 5 Spec中的定义。符合Java EE 5要求的服务器必须支持EJB2.0和2.1的CMP。这就意味着,在需要升级的程序中,可以让CMP和JPA共存。对于原有程序来说,可以一步一步的替换原有的代码和应用,可以平滑地被过渡到JPA上去。
其次,我们来看共同点,CMP和JPA都是一种O/R Mapping地解决方案,或许对于实现的程度有所不同,但在思路上基本都是以面向对象化来进行编程的。从数据库的角度来说CMP和JPA的实体对象都唯一的,而且均为数据记录的一种表现。他们的实际生命周期都与数据库息息相关。
再者,我们要注意到CMP和JPA的一些差异。
CMP
- 必须些什么:
- Entity 定义和实现
- Local接口
- Local的Home接口
- 部署的描述文件
- 可选的
- Remote接口
- Remote的Home接口
- Business Interface
JPA
- 必须些什么:
- Entity定义
- JPA Annotation或者ORM.xml
- persistence.xml
- 可选的
A. 两者具有不同的设计的思路和出发点。CMP作为一种Enterprise Bean,其在骨子里透着一种EJB的味道,而JPA的出发点是POJO,而且能够脱离容器而单独存在。CMP具有EJB的Home以及相关必需的接口,JPA完全没有这方面的需求。
另外,JPA基于的POJO概念,他的实体类是有可能被作为DTO(Data Transfer Object)来使用的。所以应当相当注意JPA的Detached Object,这对于纯粹运行于容器中的CMP来说是一个完全新的概念。特别是JPA的Entity Manager的生命周期与Transaction息息相关,这也会不知不觉中产生Detached场景,对于Lazy Load以及Cascading Updating有相当大的影响。
B.CMP利用EJB的容器,可以自己维护自己的生命周期以及一些方法。在这方面JPA是需要一些相关的辅助类来完成的,利用这些辅助类来粘合EntityManager和Entity达到CMP的功能与作用。我建议去看一下Java EE的Blueprint[REF 1]
C. JPA对于OO的抽象,继承和多态皆有比较好的支持,这对于代码重用有很大的帮助,CMP在这方面做得还很不够。
D.CMP的部署描述可以理解为JPA的Annotation/ORM.xml与persistence.xml的一个合集。有很大程度上的EJB QL可以稍加转换即可在JPA中运行(针对我比较熟悉的OpenJPA而言)。
最后,应当看到,JPA和Entity Bean的若干差异会对设计产生很大的影响。这是一个比较大的话题,我打算另立一篇文章来阐述两者的差异,并使用一些模式来解决部分实际的问题。
推荐去读一下Pro EJB 3: Java Persistence API[REF 2]的第13章,里面的内容具有相当高的参考。当然我的这些经验是没有看到这本书之前得到的,也许有了这本书可以少走很多弯路。
REF 1: http://www.parleys.com/display/PARLEYS/Java%20EE%205%20Blueprints%20(JPA) &
https://blueprints.dev.java.net/bpcatalog/ee5/persistence/
REF 2: http://www.amazon.com/Pro-EJB-Java-Persistence-API/dp/1590596455/
|