调用entityManager.getTransaction()时发生EJBException [英] EJBException when calling entityManager.getTransaction()

查看:152
本文介绍了调用entityManager.getTransaction()时发生EJBException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我得到了:

<$ p

这可能是一些微不足道的东西,但我想要一些帮助。 $ p> javax.ejb.EJBException:java.lang.IllegalStateException:非法从注入,管理的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)
私有EntityManager EM;

...

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

任何人都可以告诉我可能是什么原因?


在Java EE托管上下文中获取与EntityManager关联的EntityTransaction实例的引用是非法的。

EntityManager.getTransaction()的Java EE API文档中, a>:


返回资源级别的EntityTransaction对象。
EntityTransaction实例可以被串行使用
开始并提交多个
交易。

 返回:
EntityTransaction实例
抛出:
IllegalStateException - 如果在JTA实体管理器上调用


最后一行在这种情况下是相关的。



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


实体经理的底层
交易通过
JTA控制一个JTA实体经理。

一个实体经理,其底层
交易由
应用程序通过
EntityTransaction API控制,被称为
资源本地实体管理器。



容器管理实体管理器
必须是JTA实体管理器。
JTA
实体管理器仅针对在Java EE容器中使用
指定。


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



另外,应该注意调用 EntityManager.getTransaction()对JTA实体管理器来说没有意义。这由JPA规范在EntityTransaction接口的定义中指出:
$ b


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

关于管理JTA事务本身的话题,如果您需要自己管理事务边界(即使用bean管理的事务),注入 UserTransaction 实例。或者,如果您希望让容器管理事务,则只需使用相应的 TransactionalAttribute 值。

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



你会发现一个合适的例子,演示如何在 Hibernate EntityManager文档。如果您已经注释了您的bean类或方法,那么CMT更加微不足道;你只需要避免调用CMTs的 getEntityTransaction()方法。



如果你想了解此外,我建议阅读标题为实体管理器和持久化上下文的JPA 2.0规范的第7章。本章提供的示例演示了如何在应用程序服务器中使用JTA实体管理器(这通常是它们的地方)。

  • 资源本地实体管理器如何在应用服务器中使用。

  • 如何使用资源本地实体管理器一个Java SE应用程序。


  • This is probably something trivial, but I'd love some help.

    I get:

     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)
    

    when doing:

    @PersistenceContext(unitName = "someName")
    private EntityManager em;
    
    ...
    
    final EntityManager entityManager = getEntityManager();
    final EntityTransaction tx = entityManager.getTransaction(); // here
    

    Can anyone tell me what the cause might be ?

    解决方案

    It is illegal to obtain a reference to the EntityTransaction instance associated with the EntityManager in a Java EE managed context. From the Java EE API documentation of EntityManager.getTransaction():

    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
    

    The last line is pertinent in this context.

    When you inject the EntityManager in an EJB deployed on an application server using the @PersistenceContext or @Inject annotations, the EntityManager will be managed by the container and not by the application. A container managed entity manager must be a JTA Entity Manager; application-managed entity managers can be resource-local entity managers. This is dictated by the JPA specification:

    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.

    Inferring from the first point (regarding the IllegalStateException), you must not obtain the EntityTransaction reference for container injected EntityManagers. You may however do so, if the container injected only the EntityManagerFactory, and your application obtained the EntityManager reference by invoking EntityManagerFactory.getEntityManager.

    Additionally, it should be noted that invoking EntityManager.getTransaction() is meaningless for JTA entity managers. This is indicated by the JPA specification, in the definition of the EntityTransaction interface:

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

    On the topic of managing the JTA transaction itself, if you need to manage the transaction boundaries yourself (i.e. use bean-managed transactions), inject the UserTransaction instance. Or if you wish to have the container manage the transaction, then simply annotate the method or the bean, with the appropriate TransactionalAttribute value.

    It is usually not a good idea to use resource-local entity managers (and data sources) with bean managed or container managed transactions in an application server, but it can be done.

    You will find a suitable example demonstrating the use of BMTs with injection of the EntityManager in the Hibernate EntityManager documentation. CMTs are even more trivial if you've already annotated your bean classes or methods; you merely have to avoid invoking the the getEntityTransaction() method for CMTs to work.

    If you wish to understand further, I would recommend reading Chapter 7 of the JPA 2.0 specification, titled "Entity Managers and Persistence Contexts". The examples provided in the chapter demonstrate:

    • how JTA entity managers ought to be used in an application server (which is typically the place where they are used).
    • how resource-local entity managers may be used in an application server.
    • how resource-local entity managers can be used in a Java SE application.

    这篇关于调用entityManager.getTransaction()时发生EJBException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆