容器管理的交易

只是澄清我对容器管理事务(CMT)如何在JPA中工作的理解 –

CMT使应用程序能够明确地开始和提交事务吗?

CMT只能应用于会话和消息驱动的bean而不是pojos?

我对上述问题的理由是 – 我想知道如何从java-se应用程序以及java-ee访问实体。 我需要两个独立的持久性单元吗?

我允许自己完全重写我的答案,因为它根本不清楚,更糟糕的是,有些事情只是错误的。

事实上,您(和我)正在混合使用EJB和JPA术语。
JPA只讨论实体bean。 会话bean(包括CMT和BMT)是EJB规范的一部分。
在JPA中,我们将讨论链接到JTA或资源本地persitence单元的容器管理和应用程序管理的实体管理器。

以下是JPA规范的相关部分:

容器管理的实体管理器必须是JTA实体管理器。 JTA实体管理器仅指定用于Java EE容器。 应用程序管理的实体管理器可以是JTA实体管理器或资源本地实体管理器。

[…]

Java EE Web容器和EJB容器都需要支持JTA实体管理器和资源本地实体管理器。 在EJB环境中,通常使用JTA实体管理器。 通常,在Java SE环境中,仅支持资源本地实体管理器。

[…]

通过JTA控制其事务的实体管理器是JTA实体管理器。 JTA实体管理器参与当前的JTA事务,该事务在实体管理器外部开始并提交,并传播到底层资源管理器。

[…]

使用容器管理的实体管理器时,始终自动管理持久化上下文的生命周期,对应用程序透明,并使用JTA事务传播持久性上下文

因此,只有在java EE应用程序中使用JTA(天气或非容器管理的)实体管理器时,才需要定义2个持久性单元。

CMT是使用由Java EE容器评估的注释以声明方式定义的,然后它将透明地提供所需的事务处理。 Pojos不是由容器管理的,因此不能应用CMT。

至于你关于实体的问题。 您应该创建一个DAO层来抽象出持久性逻辑的技术细节。 你基本上可以使用一个通用的dao实现来支持JPA。 这基本上是两个环境中唯一需要不同的部分。 在容器中,您将按照注释中的定义免费获得交易。 如果在标准java se中运行,则必须自己开始/提交/回滚事务。

我建议您创建一个通用的dao实现,以声明方式定义事务并期望在容器内运行。 为了在java中使用,你有一个这个dao的装饰器,负责处理正确的事务处理,以模拟容器实际上会做什么。

我认为你真的不需要改变persistence.xml中的任何内容,但也许我错了