使用@EntityManager保存@Entity不起作用

时间:2016-10-04 07:18:22

标签: java hibernate jpa ejb jta

尝试持久化实体不起作用,但检索列表是。

以下是我的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>

豆必须是@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)

3 个答案:

答案 0 :(得分:2)

  1. 容器管理交易
  2. 这似乎没问题,您的Users无状态bean中的create方法会自动启动事务。您实体管理器参与事务,并且更改应该持久保存到数据库。在这种情况下有什么例外?

    1. Container Managed Transaction并尝试启动JTA事务
    2. 您的create方法自动启动一个事务,您尝试在代码中启动另一个JTA事务,并且您得到了一个&#39; IllegalStateException&#39;。如果要在代码中控制事务,请将配置更改为Bean Managed Transaction。

      1. Bean托管交易
      2. 您正在控制代码中的交易。代码不会抛出任何异常,但更改不会被持久化。这是因为EntityManager没有加入事务。如果在JTA事务开始之前创建了EntityManager,则需要调用joinTransaction()方法以使EntityManager加入事务:

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

答案 1 :(得分:0)

您无法从override func didReceive(_ message: MSMessage, conversation: MSConversation) { // Called when a message arrives that was generated by another instance of this // extension on a remote device. // Use this method to trigger UI updates in response to the message. guard let messageURL = message.url else { return } guard let urlComponents = NSURLComponents(url: messageURL, resolvingAgainstBaseURL: false), let queryItems = urlComponents.queryItems else { return } print("URL Components", urlComponents) print("queryItems", queryItems) for item in queryItems { print("Received \(item.name) with value \(item.value)") } }

获得交易
def __ne__

请参阅http://codepen.io/anon/pen/dpkVRj

答案 2 :(得分:0)

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