当前位置: 首页 > 面试题库 >

调用EntityManager.getTransaction()时出现EJBException

孟花蜂
2023-03-14
问题内容

这可能有些琐碎,但我希望获得一些帮助。

我得到:

 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文档中:

返回资源级的EntityTransaction对象。EntityTransaction实例可以顺序使用以开始和提交多个事务。

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

最后一行与此相关。

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

通过JTA控制基础交易的实体管理器称为JTA实体管理器。

由应用程序通过EntityTransaction API控制其基础事务的实体管理器称为资源本地实体管理器。

容器管理的实体管理器必须是JTA实体管理器。 JTA实体管理器仅指定用于Java EE容器。

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

另外,应该注意,EntityManager.getTransaction()对于JTA实体管理者而言,调用是没有意义的。JPA规范在EntityTransaction接口的定义中指出了这一点:

EntityTransaction接口用于控制资源本地实体管理器上的资源事务。

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

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

您可以在Hibernate
EntityManager文档中找到一个合适的示例来演示BMT配合使用EntityManager的使用。如果您已经注释了bean类或方法,则CMT更为简单。您只需避免调用getEntityTransaction()CMT起作用的方法。

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

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


 类似资料:
  • 我正在尝试使用Jprofiler的离线分析API将Jprofiler 8.1.4与jenkins集成。下面是写入的程序 > 开始JProfiler录制。 保存快照。 停止JProfiler录制。 导入java。io。文件导入java。io。IOException; 公共类TestJenJPIntegration{public static Connection connObj=null;publi

  • 这是我的客户端代码 这是我的Rest控制器代码: 如果我在调用后使用 String.class 作为返回类型,则相同的代码也有效。但不是响应实体类。我做错了什么,如果我需要客户端也相同的响应实体

  • 问题内容: 你好,我克服了最初的问题。我是一个完全的androidnoob,这是我的第一个应用程序。我正在Android模拟器上对此进行测试。我尝试在处连接到.NET Web服务。我得到一个。但是它在那里,URL是正确的。我怎样才能让他看到? 这发生在这里: 问题答案: 的类是误导的,因为它会抛出为400或以上的任何HTTP错误代码。 因此,它不一定是错误的URL(404),它可能是400(错误请

  • 所以我创建了自己的类,它扩展了: 我实例化了它,并将它添加到的回调中的片段事务中: 这是的布局,作为我的片段的容器: java.lang.runtimeException:无法恢复活动java.lang.nullpointerException:试图从位于Android.app.activitythread.performResumeActivit(activitythread.java:3400

  • 在Corda 3.3中,我定义了以下流程: 当我的节点执行此流时,我收到以下异常。原因是什么?

  • 我在尝试写入谷歌商店时得到一个IOException 堆栈跟踪已连接 代码如下 我正在使用App Engine SDK 1.6.4 谢谢