您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

调用EntityManager.getTransaction()时出现EJBException

调用EntityManager.getTransaction()时出现EJBException

在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实体管理器仅指定用于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章,标题为“实体管理器和持久性上下文”。本章中提供的示例演示:

其他 2022/1/1 18:14:26 有545人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶