gpt4 book ai didi

java - 调用 entityManager.getTransaction() 时出现 EJBException

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:30:07 34 4
gpt4 key购买 nike

这可能是一件微不足道的事情,但我希望得到一些帮助。

我得到:

 javax.ejb.EJBException: java.lang.IllegalStateException: Illegal to call this method from injected, managed EntityManager 
11:54:37,105 ERROR [STDERR] at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:77)
11:54:37,105 ERROR [STDERR] at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
11:54:37,105 ERROR [STDERR] at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:190)

做的时候:

@PersistenceContext(unitName = "someName")
private EntityManager em;

...

final EntityManager entityManager = getEntityManager();
final EntityTransaction tx = entityManager.getTransaction(); // here

谁能告诉我可能是什么原因?

最佳答案

在 Java EE 托管上下文中获取对与 EntityManager 关联的 EntityTransaction 实例的引用是非法的。来自 EntityManager.getTransaction() 的 Java EE API 文档:

Return the resource-level EntityTransaction object. The EntityTransaction instance may be used serially to begin and commit multiple transactions.

Returns:
EntityTransaction instance
Throws:
IllegalStateException - if invoked on a JTA entity manager

最后一行与此上下文相关。

当您使用@PersistenceContext 或@Inject 注释将EntityManager 注入(inject)部署在应用程序服务器上的EJB 中时,EntityManager 将由容器而非应用程序管理。容器管理的实体管理器必须是 JTA 实体管理器;应用程序管理的实体管理器可以是资源本地实体管理器。这是由 JPA 规范规定的:

An entity manager whose underlying transactions are controlled through JTA is termed a JTA entity manager.

An entity manager whose underlying transactions are controlled by the application through the EntityTransaction API is termed a resource-local entity manager.

A container-managed entity manager must be a JTA entity manager. JTA entity managers are only specified for use in Java EE containers.

从第一点(关于 IllegalStateException)推断,您不能为容器注入(inject)的 EntityManagers 获取 EntityTransaction 引用。但是,如果容器仅注入(inject)了 EntityManagerFactory,并且您的应用程序通过调用 EntityManagerFactory.getEntityManager 获得了 EntityManager 引用,则您可以这样做。

此外,需要注意的是调用EntityManager.getTransaction()对于JTA实体管理器是没有意义的。 JPA 规范在 EntityTransaction 接口(interface)的定义中指出了这一点:

The EntityTransaction interface is used to control resource transactions on resource-local entity managers.

关于管理 JTA 事务本身的主题,如果您需要自己管理事务边界(即使用 bean 管理的事务),请注入(inject) UserTransaction 实例。或者,如果您希望让容器管理事务,则只需使用适当的 TransactionalAttribute 注释方法或 bean。值(value)。

在应用程序服务器中将资源本地实体管理器(和数据源)与 bean 管理或容器管理事务一起使用通常不是一个好主意,但可以做到。

您将在 Hibernate EntityManager documentation 中找到一个合适的示例,演示如何使用 BMT 注入(inject) EntityManager。 .如果您已经注释了 bean 类或方法,CMT 就更简单了;您只需避免调用 CMT 工作的 getEntityTransaction() 方法。

如果您想进一步了解,我建议您阅读 JPA 2.0 规范的第 7 章,标题为“实体管理器和持久性上下文”。本章提供的示例演示:

  • 应如何在应用程序服务器中使用 JTA 实体管理器(通常是使用它们的地方)。
  • 如何在应用程序服务器中使用本地资源实体管理器。
  • 如何在 Java SE 应用程序中使用本地资源实体管理器。

关于java - 调用 entityManager.getTransaction() 时出现 EJBException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6451846/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com