javax.persistence.TransactionRequiredException:PuId =没有活动事务

时间:2014-02-05 09:01:03

标签: java jpa web-applications websphere-8

我有网络应用程序。 从表中获取效果很好

但 当我尝试更新同一个表时,通过使用JPA,我得到了异常消息:

javax.persistence.TransactionRequiredException: No active transaction for PuId =....

我正在使用transaction-type =“JTA”(容器管理)和transaction.required。 似乎

**

  

我有一个使用JTA事务类型从MDB更新的示例,并且它运行良好

**

这是我的persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="sysAdmin" transaction-type="JTA">
    <provider>
        org.apache.openjpa.persistence.PersistenceProviderImpl
    </provider>
    <jta-data-source>comp/env/jdbc/sys-SRV</jta-data-source>

    <class>com.sys.admin.jpa.sysAdminAppl</class>
    <class>com.sys.admin.jpa.sysAdminTable</class>
    <class>com.sys.admin.jpa.sysAdminTablePK</class>
    <class>com.sys.admin.jpa.Dbsys0001</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="openjpa.jdbc.DBDictionary" value="sqlserver" />
        <property name="Multithreaded" value="true" />
        <property name="openjpa.jdbc.Schema" value="dbsys" />
        <property name="openjpa.TransactionMode" value="managed"/>
        <property name="openjpa.ConnectionFactoryMode" value="managed"/>
    </properties>
</persistence-unit>
<persistence-unit name="mtmAdminUpdate" transaction-type="RESOURCE_LOCAL">
    <provider>
        org.apache.openjpa.persistence.PersistenceProviderImpl
    </provider>

    <non-jta-data-source>comp/env/jdbc/jpa</non-jta-data-source>
    <class>com.sys.admin.jpa.sysAdminAppl</class>
    <class>com.sys.admin.jpa.sysAdminTable</class>
    <class>com.sys.admin.jpa.sysAdminTablePK</class>
    <class>com.sys.admin.jpa.dbsys0001</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="openjpa.jdbc.DBDictionary" value="sqlserver" />
        <property name="Multithreaded" value="true" />
        <property name="openjpa.jdbc.Schema" value="dbsys" />
    </properties>

</persistence-unit>

我的servlet

  package com.sys.admin.servlet;

  import java.io.IOException;
  import java.io.StringWriter;
  import java.io.Writer;
  import java.util.Enumeration;

  import javax.ejb.TransactionAttribute;
  import javax.ejb.TransactionAttributeType;
  import javax.ejb.TransactionManagement;
  import javax.ejb.TransactionManagementType;
  import javax.persistence.EntityManager;
  import javax.persistence.PersistenceContext;
  import javax.persistence.PersistenceContextType;
  import javax.servlet.ServletException;
  import javax.servlet.annotation.WebServlet;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;

  import com.sys.admin.CRUD.MatamAppl;
  import com.sys.admin.jqgridPage.PageApplDetail;

  import org.codehaus.jackson.map.ObjectMapper;

 /**
 * Servlet implementation class ViewAppl
 */
 @WebServlet("/ViewAppl")
 @TransactionManagement(TransactionManagementType.CONTAINER)
 @TransactionAttribute(TransactionAttributeType.REQUIRED)
 public class ViewAppl extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @PersistenceContext(type = PersistenceContextType.TRANSACTION, unitName     = "sysAdmin")
    public EntityManager emJPA = null;

。 。 。

控制器

package com.sys.admin.jpa.controller;

import java.util.List;

import com.ibm.jpa.web.JPAManager;

import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;

import org.aspectj.weaver.patterns.ThrowsPattern;

import com.ibm.jpa.web.NamedQueryTarget;
import com.ibm.jpa.web.Action;
import com.sys.admin.jpa.SysAdminAppl;
import com.sys.admin.jpa.SysAdminApplPK;
import com.sys.admin.jpa.SysAdminTable;

@SuppressWarnings("unchecked")
@JPAManager(targetEntity = com.sys.admin.jpa.SysAdminAppl.class)
public class SysAdminApplManager {



    private EntityManager em;
    private String exceptionMessage;
.
.
.
.
@Action(Action.ACTION_TYPE.UPDATE)
    public String updateSysAdminAppl(SysAdminAppl sysAdminAppl)
            throws Exception {
        EntityManager em = getEntityManager();
        try {
            //em.getTransaction().begin();
            sysAdminAppl = em.merge(sysAdminAppl);
            //em.getTransaction().commit();
        } catch (Exception ex) {
            exceptionMessage = ex.getMessage();
            try {
                if (em.getTransaction().isActive()) {
                    em.getTransaction().rollback();
                }
            } catch (Exception e) {
                ex.printStackTrace();
                exceptionMessage = e.getMessage();
                throw e;
            }
            throw ex;
        } finally {
            em.close();
        }
        return "";
    }
.
.
.

这是我的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>sysAdmin</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <resource-ref  id="adminDb">
        <description></description>
        <res-ref-name>aliasDataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>


</web-app>

IBM的Web-ext.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-ext
    xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_1.xsd"
    version="1.1">

    <reload-interval value="3"/><resource-ref name="resourceSqlserver" isolation-level="TRANSACTION_READ_UNCOMMITTED" connection-management-policy="DEFAULT"/>
    <enable-directory-browsing value="false"/>
    <enable-file-serving value="true"/>
    <enable-reloading value="true"/>
    <enable-serving-servlets-by-class-name value="true" />

</web-ext>

IBM的Web-bnd.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-bnd 
    xmlns="http://websphere.ibm.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_1.xsd"
    version="1.1">

    <virtual-host name="default_host" />

    <resource-ref name="aliasDataSource"
        binding-name="comp/env/jdbc/SYS-SRV">
    </resource-ref>

</web-bnd>

2 个答案:

答案 0 :(得分:1)

据我所知,CMP事务是由EJB设置的,而不是J2EE6规范中的Servlet。

我过去曾遇到类似的问题,这与我对这一点的误解有关。

如果你看这里:http://docs.oracle.com/javaee/6/tutorial/doc/bncij.html,文档 很清楚地说明了这一点:

  

在具有容器管理的事务划分的企业bean中,   EJB容器设置事务的边界。您可以使用   任何类型的企业bean的容器管理事务:   会话或消息驱动。容器管理的事务简化   开发因为企业bean代码没有明确标记   交易的界限。代码不包含语句   开始和结束交易。默认情况下,如果没有事务   指定了分界,企业bean使用容器管理   交易划分。

     

通常,容器在a之前立即开始一个事务   enterprise bean方法刚刚启动并提交事务   方法退出。每种方法都可以与单个方法相关联   交易。 a中不允许嵌套或多个事务   方法

换句话说......将持久性代码分解为EJB,并从servlet中调用它。

答案 1 :(得分:0)

您需要在调用JPA之前启动JTA事务:使用@Resource UserTransaction userTran,然后在调用JPA时使用userTran.begin() / userTran.commit()