使用@EntityManager 保存@Entity 不工作
Save @Entity using @EntityManager not working
尝试持久化一个实体是行不通的,但检索列表是行得通的。
下面是我的 Bean:(a)
@Stateless
public class UsersClass {
@PersistenceContext(unitName = "unit")
private EntityManager em;
public UsersClass () {}
public void create(Users entity) {
em.persist(entity);
}
}
persistence.xml
如下:
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="unit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/ds</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
</persistence>
Bean 必须是@Stateless。 Above, setup executes fine - no exception or anything but nothing gets saved in DB also
.
尝试了提到的内容here。不确定我是否做对了,但出现了异常。
我也尝试了提到的here并修改如下:(b)
@Stateless
public class UsersClass {
@PersistenceContext(unitName = "unit")
private EntityManager em;
@Resource
private SessionContext sessionContext;
public UsersClass () {}
public void create(Users entity) {
UserTransaction userTxn = sessionContext.getUserTransaction();
try {
userTxn.begin();
getEntityManager().persist(entity);
userTxn.commit();
} catch(Throwable e){
e.printStackTrace();
try {
userTxn.rollback();
} catch (IllegalStateException | SecurityException | SystemException e1) {
e1.printStackTrace();
}
}
}
}
但得到了以下堆栈跟踪 -
Caused by: java.lang.IllegalStateException: Only session beans with bean-managed transactions can obtain UserTransaction
at com.sun.ejb.containers.EJBContainerTransactionManager.getUserTransaction(EJBContainerTransactionManager.java:566)
at com.sun.ejb.containers.BaseContainer.getUserTransaction(BaseContainer.java:995)
at com.sun.ejb.containers.AbstractSessionContextImpl.getUserTransaction(AbstractSessionContextImpl.java:120)
所以根据我的阅读,我认为将 @TransactionManagement(TransactionManagementType.BEAN)
添加到我的 class 应该会有所帮助。事实上,异常消失了,但数据库中没有任何内容。
也尝试过 - entitymanager.getTransaction().begin() 和 commit() 但我得到了下面的堆栈跟踪
Caused by: java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.hibernate.internal.AbstractSharedSessionContract.getTransaction(AbstractSharedSessionContract.java:360)
at org.hibernate.internal.AbstractSessionImpl.getTransaction(AbstractSessionImpl.java:23)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.getTransaction(EntityManagerWrapper.java:806)
如果有人能指出缺少的代码,那将对我很有帮助。
更新 1 -
我也尝试了以下一组更改 (b)
userTxn.begin();
getEntityManager().joinTransaction();
getEntityManager().persist(entity);
userTxn.commit();
低于堆栈跟踪 -
org.hibernate.resource.transaction.backend.jta.internal.JtaPlatformInaccessibleException: Unable to access TransactionManager or UserTransaction to make physical transaction delegate
at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.makePhysicalTransactionDelegate(JtaTransactionCoordinatorImpl.java:229)
at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.getTransactionDriverControl(JtaTransactionCoordinatorImpl.java:203)
at org.hibernate.engine.transaction.internal.TransactionImpl.<init>(TransactionImpl.java:37)
at org.hibernate.internal.AbstractSharedSessionContract.accessTransaction(AbstractSharedSessionContract.java:372)
at org.hibernate.internal.AbstractSharedSessionContract.markForRollbackOnly(AbstractSharedSessionContract.java:342)
at org.hibernate.internal.ExceptionConverterImpl.handlePersistenceException(ExceptionConverterImpl.java:271)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:148)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
at org.hibernate.internal.SessionImpl.joinTransaction(SessionImpl.java:3736)
at org.hibernate.internal.SessionImpl.joinTransaction(SessionImpl.java:3718)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.joinTransaction(EntityManagerWrapper.java:990)
您不能从 EntityManager
获取交易吗
em.getTransaction().begin ();
见https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#getTransaction--
您正在使用 JTA 事务。在这种情况下,您不需要管理事务。它是容器管理的。我认为你应该在创建函数上使用@Transactional 注释,或者如果你想自己管理事务那么你需要使用事务类型 LOCAL 并且在这种情况下你需要从 entitymanager 工厂获取 entitymanager 实例。
- 容器管理事务
这似乎没问题,Users
无状态 bean 中的创建方法会自动启动事务。您的 entityManager 参与事务并且更改应该持久保存到数据库中。这种情况下的例外情况是什么?
- 容器管理事务并尝试启动 JTA 事务
您的创建方法自动启动一个事务,您试图在代码中启动另一个 JTA 事务,但您得到了 'IllegalStateException'。如果想在代码中控制事务,将配置改为Bean Managed Transaction。
- Bean 管理事务
您正在控制代码中的交易。该代码不会抛出任何异常,但不会保留更改。这是因为 EntityManager 没有加入事务。如果在JTA事务开始之前创建了EntityManager,需要调用方法joinTransaction()让EntityManager加入事务:
userTxn.begin();
EntityManager em = getEntityManager();
em.joinTransaction();
em.persist(entity);
userTxn.commit();
尝试持久化一个实体是行不通的,但检索列表是行得通的。
下面是我的 Bean:(a)
@Stateless
public class UsersClass {
@PersistenceContext(unitName = "unit")
private EntityManager em;
public UsersClass () {}
public void create(Users entity) {
em.persist(entity);
}
}
persistence.xml
如下:
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="unit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>jdbc/ds</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
</properties>
</persistence-unit>
</persistence>
Bean 必须是@Stateless。 Above, setup executes fine - no exception or anything but nothing gets saved in DB also
.
尝试了提到的内容here。不确定我是否做对了,但出现了异常。
我也尝试了提到的here并修改如下:(b)
@Stateless
public class UsersClass {
@PersistenceContext(unitName = "unit")
private EntityManager em;
@Resource
private SessionContext sessionContext;
public UsersClass () {}
public void create(Users entity) {
UserTransaction userTxn = sessionContext.getUserTransaction();
try {
userTxn.begin();
getEntityManager().persist(entity);
userTxn.commit();
} catch(Throwable e){
e.printStackTrace();
try {
userTxn.rollback();
} catch (IllegalStateException | SecurityException | SystemException e1) {
e1.printStackTrace();
}
}
}
}
但得到了以下堆栈跟踪 -
Caused by: java.lang.IllegalStateException: Only session beans with bean-managed transactions can obtain UserTransaction
at com.sun.ejb.containers.EJBContainerTransactionManager.getUserTransaction(EJBContainerTransactionManager.java:566)
at com.sun.ejb.containers.BaseContainer.getUserTransaction(BaseContainer.java:995)
at com.sun.ejb.containers.AbstractSessionContextImpl.getUserTransaction(AbstractSessionContextImpl.java:120)
所以根据我的阅读,我认为将 @TransactionManagement(TransactionManagementType.BEAN)
添加到我的 class 应该会有所帮助。事实上,异常消失了,但数据库中没有任何内容。
也尝试过 - entitymanager.getTransaction().begin() 和 commit() 但我得到了下面的堆栈跟踪
Caused by: java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
at org.hibernate.internal.AbstractSharedSessionContract.getTransaction(AbstractSharedSessionContract.java:360)
at org.hibernate.internal.AbstractSessionImpl.getTransaction(AbstractSessionImpl.java:23)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.getTransaction(EntityManagerWrapper.java:806)
如果有人能指出缺少的代码,那将对我很有帮助。
更新 1 -
我也尝试了以下一组更改 (b)
userTxn.begin();
getEntityManager().joinTransaction();
getEntityManager().persist(entity);
userTxn.commit();
低于堆栈跟踪 -
org.hibernate.resource.transaction.backend.jta.internal.JtaPlatformInaccessibleException: Unable to access TransactionManager or UserTransaction to make physical transaction delegate
at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.makePhysicalTransactionDelegate(JtaTransactionCoordinatorImpl.java:229)
at org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.getTransactionDriverControl(JtaTransactionCoordinatorImpl.java:203)
at org.hibernate.engine.transaction.internal.TransactionImpl.<init>(TransactionImpl.java:37)
at org.hibernate.internal.AbstractSharedSessionContract.accessTransaction(AbstractSharedSessionContract.java:372)
at org.hibernate.internal.AbstractSharedSessionContract.markForRollbackOnly(AbstractSharedSessionContract.java:342)
at org.hibernate.internal.ExceptionConverterImpl.handlePersistenceException(ExceptionConverterImpl.java:271)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:148)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
at org.hibernate.internal.SessionImpl.joinTransaction(SessionImpl.java:3736)
at org.hibernate.internal.SessionImpl.joinTransaction(SessionImpl.java:3718)
at com.sun.enterprise.container.common.impl.EntityManagerWrapper.joinTransaction(EntityManagerWrapper.java:990)
您不能从 EntityManager
em.getTransaction().begin ();
见https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#getTransaction--
您正在使用 JTA 事务。在这种情况下,您不需要管理事务。它是容器管理的。我认为你应该在创建函数上使用@Transactional 注释,或者如果你想自己管理事务那么你需要使用事务类型 LOCAL 并且在这种情况下你需要从 entitymanager 工厂获取 entitymanager 实例。
- 容器管理事务
这似乎没问题,Users
无状态 bean 中的创建方法会自动启动事务。您的 entityManager 参与事务并且更改应该持久保存到数据库中。这种情况下的例外情况是什么?
- 容器管理事务并尝试启动 JTA 事务
您的创建方法自动启动一个事务,您试图在代码中启动另一个 JTA 事务,但您得到了 'IllegalStateException'。如果想在代码中控制事务,将配置改为Bean Managed Transaction。
- Bean 管理事务
您正在控制代码中的交易。该代码不会抛出任何异常,但不会保留更改。这是因为 EntityManager 没有加入事务。如果在JTA事务开始之前创建了EntityManager,需要调用方法joinTransaction()让EntityManager加入事务:
userTxn.begin();
EntityManager em = getEntityManager();
em.joinTransaction();
em.persist(entity);
userTxn.commit();