只是澄清我对容器管理事务(CMT)如何在JPA中工作的理解 -
CMT使应用程序能够明确地开始和提交事务吗?
CMT只能应用于会话和消息驱动的bean而不是pojos?
我对上述问题的理由是 - 我想知道如何从java-se应用程序以及java-ee访问实体。我需要两个独立的持久性单元吗?
答案 0 :(得分:4)
我允许自己完全重写我的答案,因为它根本不清楚,更糟糕的是,有些事情只是错误。
事实是你(和我)正在混合使用EJB和JPA术语
JPA只讨论实体bean。会话bean(包括CMT和BMT)是EJB规范的一部分。
在JPA中,我们将讨论链接到JTA或资源本地persitence单元的容器管理和应用程序管理的实体管理器。
以下是JPA规范的相关部分:
容器管理的实体管理器必须是JTA实体管理器。仅指定JTA实体管理器 用于Java EE容器。 应用程序管理的实体管理器可以是JTA实体管理器或资源本地实体 管理器。
[...]
Java EE中需要支持JTA实体管理器和资源本地实体管理器 Web容器和EJB容器。在EJB环境中,通常使用JTA实体管理器。 通常,在Java SE环境中,仅支持资源本地实体管理器。
[...]
通过JTA控制交易的实体经理是JTA实体经理。 JTA 实体管理器参与当前的JTA事务,该事务在外部开始并提交 实体管理器并传播到底层资源管理器。
[...]
使用容器管理的实体管理器时,持久化上下文的生命周期始终如此 自动,透明地管理应用程序,并使用传播持久性上下文 JTA交易
因此,只有在java EE应用程序中使用JTA(天气或不是容器管理的)实体管理器时,才需要定义2个持久性单元。
答案 1 :(得分:1)
使用由Java EE容器评估的注释以声明方式定义CMT,然后该注释将透明地提供所需的事务处理。 Pojos不是由容器管理的,因此不能应用CMT。
关于实体的问题。您应该创建一个DAO层来抽象出持久性逻辑的技术细节。你基本上可以使用一个通用的dao实现来支持JPA。这基本上是两个环境中唯一需要不同的部分。在容器中,您将按照注释中的定义免费获得交易。如果在标准java se中运行,则必须自己开始/提交/回滚事务。
我建议您创建一个通用的dao实现,以声明方式定义事务并期望在容器内运行。为了在java中使用,你有一个这个dao的装饰器,负责处理正确的事务处理,以模拟容器实际上会做什么。
我认为你真的不需要改变persistence.xml中的任何内容,但也许我错了