3

可以@PersistenceUnit在 JPA 中与 JTA 一起使用吗?如果是这样,怎么可能?

根据http://tomee.apache.org/jpa-concepts.html

<persistence-unit transaction-type="RESOURCE_LOCAL"> [...]

  • 您必须使用 EntityManagerFactory 来获取 EntityManager
  • [...]
  • EntityManagerFactory 只能通过@PersistenceUnit 注解注入(不是@PersistenceContext)

<persistence-unit transaction-type="JTA"> [...]

  • EntityManager 只能通过@PersistenceContext 注解注入(不是@PersistenceUnit)

我有一个类似的代码,它同时使用 JTA @PersistenceUnit。但有时我NullPointerException在访问事务时遇到(定义为@Resource)。

4

2 回答 2

0

使用 JTA 意味着您将工作委托给容器。您可以使用UserTransaction. 您的报价包含您想知道的所有答案。用PersistenceUnit得到一个EntityManager不会工作。

如果您正在使用RESOURCE_LOCAL,您需要对交易本身负责,使用EntityManager.getTransaction(). 实体管理器由EntityManagerFactory. 要获得该工厂,您可以使用PersistenceUnit.

所以简单的答案是否定的,如果您依赖容器管理的实体管理器。

作为示例,请参见http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html

Application Managed Entity Managers =RESOURCE_LOCAL可以使用UserTransaction(它们是 JTA 的一部分)。

于 2013-04-24T10:58:31.230 回答
0

实体经理是什么意思???如果我是一个天真的程序员,我可以简单地解释一些管理实体的东西,实际上它的意思是一样的。

在此处输入图像描述

实体管理器是在实体管理器工厂的帮助下实例化的。与数据库的连接由实体管理器管理,即它提供对数据库执行操作的功能。因此我们可以说,如果应用程序需要多个数据库连接,将为特定数据库构建一个 EntityManagerFactory,它提供了一种构建多个 EntityManager 实例的有效方法(如果需要,即使是单个实体管理器实例也可以根据您可能的要求来工作选择多个实例)用于每个 HTTP 请求所需的数据库。我们将借助一个例子来理解这一点。假设我们有一个数据库:A,有一个关系表 B 和 C。所以对于 A,实体管理器工厂的一个实例将被实例化。现在,如果我们想要对表 B 执行任何更新并假设对表 C 进行删除操作,则可以实例化两个不同的实体管理器,或者可以对两者使用相同的实体管理器实例。实体管理器工厂本身的实例化被认为效率较低,但由于它是一次性活动,因此它是可管理的任务,因为实体管理器工厂一旦实例化,它将服务于整个应用程序实例化的实体管理器与持久性上下文相关联。

@PersistenceUnit(unitName = "MyDatabase")
EntityManagerFactory emf;
EntityManager entityManager = emf.createEntityManager();

或者

@PersistenceContext(unitName = "MyDatabase") 
private EntityManager entityManager;

PersistenceUnit 注入一个 EntityManagerFactory,而 PersistenceContext 注入一个 EntityManager。除非您确实需要手动管理 EntityManager 生命周期,否则通常最好使用 PersistenceContext。EntityManagerFactory 定义了另一种实例化 EntityManager 的方法,该方法与工厂一样,将属性映射作为参数。当必须指定 EntityManagerFactory 的默认用户名和密码以外的用户名和密码时,此表单很有用:

Map properties = new HashMap(); 
properties.put("javax.persistence.jdbc.user", "kashyap");
properties.put("javax.persistence.jdbc.password","kashyap"); 
EntityManager em = emf.createEntityManager(properties);

在持久性上下文中,管理实体实例及其生命周期。实体实例是指一个实体的实例,每个实体指定数据库中的关系表。实体管理器实际上是一个接口,它提供了创建和删除持久实体实例、通过主键查找实体以及查询实体的方法,因此这些功能一起分组在我们执行的操作下。修改数据库内容的操作需要活动事务。事务由从 EntityManager 获得的 Entity Transaction 实例管理。精确定义:- 实体管理器由持久性单元定义。持久性单元定义了由应用程序相关或分组的所有类的集合,并且必须在它们到单个数据库的映射中并置。下面我正在编写一个代码片段以便更好地理解:-

try {
        em.getTransaction().begin();
        // Operations that modify the database should come here.
        em.getTransaction
        /**
        *getTransaction() EntityManager's method Return the resource-level EntityTransaction object. See JavaDoc Reference Page
        */
        em.getTransaction().commit();
  }
  finally {
        if (em.getTransaction().isActive())
            em.getTransaction().rollback();
  }

让我们按照 JPA 规范进行:- 1) 扩展与事务 - 范围:默认情况下,使用事务持久性上下文,这意味着所有更改都被刷新,并且所有托管实体在当前事务提交时都变得分离。扩展范围仅适用于有状态 EJB,它甚至非常有意义,因为有状态 bean 可以保存状态,因此可以说一种业务方法的结束并不一定意味着事务的结束。使用无状态 bean,它有一个不同的方面 - 我们有业务方法必须在业务方法完成时结束。===> 一种方法 = 一种交易;无状态 Bean 只允许事务范围的实体管理器您可以控制在 EntityManager 注入期间 EntityManager 是扩展的还是事务性的:-

@PersistenceContext (type = javax.persistence.PersistenceContextType.EXTENDED)
    EntityManager emng;

默认情况下,它的 javax.persistence.PersistenceContextType.TRANSACTION Extended 和 Transaction Scoped PersistenceContext 仅在容器管理的 EntityManager 的情况下才允许使用。是时候加强一点了:容器管理与应用程序管理 2)容器管理与应用程序管理:

@PersistenceContext
EntityManager emng;

上面的语句授权 Container 为你注入实体管理器,因此是 Container-Managed。或者,您可以使用 EntityManagerFactory 自己创建一个 EntityManager 但这次注入会有所不同 -

@PersistenceUnit
EntityManagerFactory emf;

现在要获取您需要调用的 EntityManager

emf.createEntityManager();

在这里 - 您正在使用应用程序管理的持久性上下文。现在您负责创建和删除 EntityManager。在阅读下一段之前集中注意力,因为这就是纠结的上下文,我试图解决 - 如果你想控制创建的 EM,你可以使用 createEntityManager - 例如,如果你需要跨多个涉及的 bean 移动创建的 EntityManager trasaction - 容器不会为您执行此操作,并且每次调用 createEntityManager() 时,您都会创建一个连接到新 PersistenceContext 的 EntityManager。您可以将 CDI 用于 EntityManager 的共享。请继续关注 Entity Transaction - JPA 和 Resource-local,将发布关于它的详细讨论。希望它对上下文有一个简要的了解。&随时发布查询。

从这里阅读第二部分

于 2015-12-30T08:31:51.913 回答