复合持久性单元 - Java EE
在 Java EE 中处理多个实体管理器(即多个持久性单元)的方法是使用复合持久性单元 (CPU)。这种复合持久性单元可以从 EE Web 应用程序中的一个点(数据层)进行评估。不过,这需要是一个@Stateless
EE bean 才能与@PersistenceContext
.
已引入复合持久性单元以使在各种 Java 应用程序中重用实体类成为可能。CPU 是企业架构的一个特性。我选择使用 EclipseLink 作为展示,因为我从正在运行的生产应用程序中获得了积极的经验。
介绍
在某些情况下,实体包含服务器环境中更多 Web 服务所需的一般数据。以一般的“名称-地址”实体、“用户密码角色”实体、“文档关键字索引”实体等为例。复合持久性单元实现有助于每个实体定义的来源在只有一个地方('单点定义')。这些实体定义随后可以包含在需要此实体访问的每个 Java Web 应用程序中。
复合持久性单元的工作
以下教程说明了复合持久性单元的工作:EclipseLink 复合持久性单元
复合持久性单元的概念首先定义成员持久性单元。每个成员持久性单元可能与不同的数据库相关联,但成员持久性单元也可以都引用同一个实际数据库。我有后者的经验,其中 EclipseLink(版本 2.6.4)与一个 Postgress 数据库结合使用。
需要 Maven 来实现所需的模块化方法。
persistence.xml 中的设置
复合持久性单元成员定义如下:@Entity
在专用 Maven 模块中对一组相关实体(Java 类)进行逐个编程。在这个 Maven 模块中还定义了一个复合持久性单元成员(重要!)。复合单元成员PuPersonData指的是这组表征人员数据的相关实体。将成员持久化单元 PuPersonData 定义为 (
<persistence-unit name="PuPersonData" transaction-type="JTA">
...
<jta-data-source>jdbc/PostgresDs</jta-data-source>
...
)。
在第二个 Maven 模块中,定义另一个复合持久性单元成员 PuWebTraffic (
<persistence-unit name="PuWebTraffic" transaction-type="JTA">
...
<jta-data-source>jdbc/PostgresDs</jta-data-source>
...
)。@Entity
此处包括存储有关 Web 事务、登录、会话等数据的其他实体(用.
两个持久性单元成员在其 XML 定义中都有以下属性:
<properties>
<property name="eclipselink.composite-unit.member" value="true"/>
...
</properties>
复合持久性单元
我们现在在第三个 Maven 模块中定义复合持久性单元 CPuPersonSessionData,它包括持久性单元成员 PuPersonData 和 PuWebTraffic。
<persistence-unit name="CPuPersonSessionData" transaction-type="JTA">
这个复合持久性单元 CPuPersonSessionData 通过包含两个相关 Maven 模块编译产生的 jars 来引用两个持久性单元成员,PuPersonData 和 PuWebTraffic。
...
<jar-file>PuPersonData.jar</jar-file>
<jar-file>PuWebTraffic.jar</jar-file>
...
在复合持久化单元的 XML-definition 中,需要设置以下属性
<properties>
<property name="eclipselink.composite-unit" value="true"/>
...
</properties>
此设置可确保 Java EE 对待复合持久性单元的方式与其持久性单元成员不同。
Java中持久化单元的使用
在将使用人员数据和交通数据存储和检索实体的 Java Web 应用程序中,仅包含复合持久性单元
@Stateless
public class DataLayer {
@PersistenceUnit(unitName="CPuPersonSessionData")
EntityManager em;
...
现在可以对包含在复合实体成员之一中的每个实体执行正常的“em”操作persist
,例如find
和。merge
在 Payara 下,这个复合持久性单元不需要 XA 事务来处理与每个持久性单元成员相关的实体。
马文
Maven父POM 文件需要包含相关模块的规范。
...
<modules>
<module>PersonData</module>
<module>WebTraffic</module>
<module>PersonSessionData</module>
</modules>
...
每个模块的POM-file都需要配置成一个普通的Maven-project,参考父POM-file。
陷阱:
- 您需要正确配置 Maven 多模块项目,这可能有些棘手。每个复合持久性单元成员构成一个单独的 Maven 模块。此外,复合持久性单元是一个单独的 Maven 模块。成员需要首先按照 Maven 顺序编译。
- 编译复合持久化单元的模块时,需要找到复合持久化单元中的“jar”。
- 每个复合持久性单元成员的实体需要在生成的“jar”中直接在“类”目录中可用(通过 Maven 向实体添加额外路径是可能的,但很复杂)。
- 持久性单元成员的“jars”需要在“类”目录中可用,以便复合持久性单元找到它们。
获得的好处是一个整洁的企业数据层,它与可重用实体一起工作,每个实体都有一个中心定义。此外,还可以执行跨单元的原生 SQL 查询。我也得到了这个工作。
文档指出,当复合持久性单元成员在不同的实际数据库上运行时,跨单元本机查询将不起作用。这仍应得到验证。