在过滤器中持久化对象时,“没有活动事务”和“在使用JTA时不能使用EntityTransaction”?

时间:2014-07-16 19:26:54

标签: java-ee jpa jta

我想使用过滤器将所有请求记录到我的Web服务器。

首先,我尝试了在EJB和Web服务类中使用的常规方法。一旦我试图坚持,我的程序就会失败。我可以查询(此处未显示):

@PersistenceContext(unitName = "ConsoleManagement")
protected EntityManager em;
...
private void someMethod(){
        Request userRequest = new Request();
        userRequest.setApikey(apikey);
        userRequest.setFormat(requestedFormat);
        userRequest.setMethod(method);
        userRequest.setRequestIp(ip);
        userRequest.setRequestUrl(requestUrl);
        em.persist(userRequest); // fails here
        em.flush();
}

错误:

[ERROR   ] SRVE0315E: An exception occurred: com.ibm.ws.webcontainer.webapp.WebAppErrorReport: javax.persistence.TransactionRequiredException: No active transaction for PuId=WebApi#WebApi.war#PersistenceUnitName
    at com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:250)

从中我收集了(虽然找不到任何文档)过滤器不是容器管理的。

然后我尝试了以下两个:

@PersistenceContext(unitName = "ConsoleManagement")
protected EntityManager em;
...
private void someMethod(){
        Request userRequest = new Request();
        userRequest.setApikey(apikey);
        userRequest.setFormat(requestedFormat);
        userRequest.setMethod(method);
        userRequest.setRequestIp(ip);
        userRequest.setRequestUrl(requestUrl);
        em.getTransaction().begin(); // fails here
        em.persist(userRequest);
        em.flush();
        em.getTransaction().commit()
}


@PersistenceUnit(unitName = "ConsoleManagement")
EntityManagerFactory emf;

public void someMethod() {
    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin(); // fails here
    em.persist(userRequest);
    em.flush();
    em.getTransaction().commit();
    em.close();
}

两种情况都有错误:

[ERROR   ] SRVE0315E: An exception occurred: com.ibm.ws.webcontainer.webapp.WebAppErrorReport: java.lang.IllegalStateException: 
Exception Description: Cannot use an EntityTransaction while using JTA.

[编辑]如果我通过@PersistenceUnit注入一个EntityManagerFactory并删除了em.getTransaction()。begin(),我会得到一个不同的错误。

@PersistenceUnit(unitName = "ConsoleManagement")
EntityManagerFactory emf;

public void someMethod() {
    EntityManager em = emf.createEntityManager();
    //em.getTransaction().begin(); 
    em.persist(userRequest);
    em.flush(); // fails here now
    //em.getTransaction().commit();
    em.close();
}

错误:

[ERROR   ] SRVE0315E: An exception occurred: com.ibm.ws.webcontainer.webapp.WebAppErrorReport: javax.persistence.TransactionRequiredException: 
Exception Description: No externally managed transaction is currently active for this thread

我现在有点卡住了。

[编辑] 持久性单位:

<persistence-unit name="ConsoleManagement">
    <description>This unit manages user data including user information, user projects, and project api keys</description>
    <jta-data-source>jdbc/db2dbcpdb/develop</jta-data-source>
    <class>com.utoronto.websphere.jaxrs.entities.Project</class>
    <class>com.utoronto.websphere.jaxrs.entities.User</class>
    <class>com.utoronto.websphere.jaxrs.entities.Api</class>
    <class>com.utoronto.websphere.jaxrs.entities.Apikey</class>
    <class>com.utoronto.websphere.jaxrs.entities.Version</class>
    <class>com.utoronto.websphere.jaxrs.entities.Request</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>

1 个答案:

答案 0 :(得分:3)

规范声明如果未指定transaction-type,则Java EE环境中的默认值为JTA。由于您使用的是容器管理的EntityManager,因此您无法像在Java SE环境中那样开始/提交/回滚EntityTransaction

您可以通过@Resource注释访问UserTransaction

public class MyFilter implements Filter {
    @Resource
    UserTransaction utx;

    @PersistenceContext
    EntityManager em;

    private void doSomething() {
        // ...
        utx.begin();
        em.persist(foo);
        utx.commit();
    }
}