【问题标题】:Save @Entity using @EntityManager not working使用 @EntityManager 保存 @Entity 不起作用
【发布时间】:2017-02-12 06:28:10
【问题描述】:

尝试持久化实体无效,但检索列表有效。

下面是我的 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) 添加到我的班级应该会有所帮助。确实,异常消失了,但数据库中没有任何内容。

也尝试过 - 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)

【问题讨论】:

  • 您要坚持的实体是什么?在您的 create 方法中,您将 Users 对象传递给您的 entityManager,但 Users 是您的无状态 EJB 的类

标签: java hibernate jpa ejb jta


【解决方案1】:
  1. 容器管理事务

这似乎没问题,您的 Users 无状态 bean 中的 create 方法会自动启动事务。您的 entityManager 参与了事务,并且更改应该被持久化到数据库中。在这种情况下有什么例外?

  1. 容器托管事务并尝试启动 JTA 事务

您的 create 方法自动启动一个事务,您尝试在代码中启动另一个 JTA 事务并且得到一个“IllegalStateException”。如果要控制代码中的事务,请将配置更改为 Bean Managed Transaction。

  1. Bean 托管事务

您正在控制代码中的事务。该代码不会引发任何异常,但不会保留更改。这是因为 EntityManager 没有加入事务。如果在 JTA 事务开始之前创建了 EntityManager,则需要调用 joinTransaction() 方法使 EntityManager 加入事务:

userTxn.begin();
EntityManager em = getEntityManager();
em.joinTransaction();
em.persist(entity);
userTxn.commit();

【讨论】:

  • 我在您最初发表评论后更新了问题,并回答了1。如您的回答中所述,我还尝试了3 和设置b。也为此更新了问题。
  • getEntityManager 方法只是一个吸气剂吗?如果没有,能否在问题中也加入这个方法的代码
  • 可能你需要在persistence.xml中设置属性'hibernate.transaction.jta.platform'
  • 我没有 EntityManager em 的任何设置器。我正在使用@PersistenceContext(unitName = "unit")getEntityManager 将其注入以获取它。
  • 根据stacktrace,我认为你使用的是GlassFish,如果是这样,你需要在persistence.xml文件中添加&lt;property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" /&gt;
【解决方案2】:

你不能从EntityManager获取交易

em.getTransaction().begin ();

https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#getTransaction--

【讨论】:

  • 我试过了,我得到了java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()
  • 那么你能把 transaction-type 改成 LOCAL 吗?
  • 没有。我应该使用JTA
【解决方案3】:

您正在使用 JTA 事务。在这种情况下,您不需要管理事务。它是容器管理的。我认为您应该在 create 函数上使用 @Transactional 注释,或者如果您想自己管理事务,那么您需要使用事务类型 LOCAL 并且在这种情况下您需要从 entitymanager 工厂获取 entitymanager 实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多