我有网络应用程序。 从表中获取工作正常
但是 当我尝试使用 JPA 更新同一个表时,我收到异常消息:
javax.persistence.TransactionRequiredException: No active transaction for PuId =....
我正在使用 transaction-type="JTA"(容器管理)和 transaction.required。 看来是这样的
**
I have an example of an update from MDB using JTA transaction type and there it's works well
**
这是我的 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;
。 。 。 .
Controller
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>
最佳答案
据我所知,CMP 事务是由 EJB 设置的,而不是 J2EE6 规范中的 Servlet。
我过去也遇到过类似的问题,这与我对这一点的误解有关。
如果你看这里:http://docs.oracle.com/javaee/6/tutorial/doc/bncij.html ,文档 非常清楚地阐述了这一点:
In an enterprise bean with container-managed transaction demarcation, the EJB container sets the boundaries of the transactions. You can use container-managed transactions with any type of enterprise bean: session or message-driven. Container-managed transactions simplify development because the enterprise bean code does not explicitly mark the transaction’s boundaries. The code does not include statements that begin and end the transaction. By default, if no transaction demarcation is specified, enterprise beans use container-managed transaction demarcation.
Typically, the container begins a transaction immediately before an enterprise bean method starts and commits the transaction just before the method exits. Each method can be associated with a single transaction. Nested or multiple transactions are not allowed within a method.
换句话说...将持久性代码分解为 EJB,并从 servlet 中调用它。
关于javax.persistence.TransactionRequiredException : No active transaction for PuId=,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21572656/