首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用entityManager在JPA中启动事务

如何使用entityManager在JPA中启动事务
EN

Stack Overflow用户
提问于 2017-03-20 17:45:26
回答 4查看 46.4K关注 0票数 9

我已经开始开发一个使用spring、hibernate、JPA、SOAP webservices的应用程序。现在有一个要求,即必须在事务中运行某些查询。如果其中任何一个失败,整个事务都应该回滚。

dao层的代码如下:

代码语言:javascript
复制
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
import org.hibernate.Session;

    public class BillDAOImpl implements BillDao{

             @PersistenceContext(type = PersistenceContextType.EXTENDED)
             private EntityManager em;

             public boolean processBills() throws Exception{

             EntityTransaction tx = null;
             Session session = null;

             try{

                 session = em.unwrap(Session.class);
                 tx = em.getTransaction();

                 Bill bill = em.find(Bill.class, billId);

                 //session.beginTransaction();
                 tx.begin();
                 ...
                 ...
                 em.persist(bill);
                 ...
                 ...
                 em.merge(<other object>);
                 ...
                 ...
                 //session.getTransaction().commit();
                 tx.commit();
             } catch(){
             }

             }

    }

当它执行tx = em.getTransaction()时,它会给出以下错误:

代码语言:javascript
复制
java.lang.IllegalStateException: Cannot execute getTransaction() on a container-managed EntityManager

其他与事务相关的属性如下:

代码语言:javascript
复制
<bean id="tuneEntityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:persistenceXmlLocation="classpath*:META-INF/tune-persistence.xml"
        p:persistenceUnitName="tunePersistenceUnit" p:loadTimeWeaver-ref="loadTimeWeaver"
        p:jpaVendorAdapter-ref="jpaVendorAdapter" p:jpaDialect-ref="jpaDialect"
        p:dataSource-ref="tuneDbDataSource">
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.BTMTransactionManagerLookup
                </prop>
                <prop key="net.sf.ehcache.configurationResourceName">/${tune-db.ehcache.config.file}</prop>
                <prop key="hibernate.transaction.flush_before_completion">false</prop>              
                <prop key="hibernate.default_schema">${tune-db.schema}</prop>
                <prop key="org.hibernate.envers.default_schema">${tune-db.schema}</prop>
                <prop key="javax.persistence.validation.mode">${tune-db.data.validation}</prop>
                <prop key="hibernate.connection.isolation">3</prop>
                <prop key="hibernate.connection.release_mode">auto</prop>
                <prop key="hibernate.show_sql">${tune-db.hibernate.show-sql}</prop>
                <prop key="hibernate.format_sql">${tune-db.hibernate.format-sql}</prop>
            </props>
        </property>     
    </bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="tuneEntityManagerFactory" />
    </bean>

当我使用session.beginTransaction()session.getTransaction().commit()时,它工作正常。

但是,我想用entityManager中的transaction替换它。那该怎么办呢?

EN

回答 4

Stack Overflow用户

发布于 2017-03-20 17:51:11

尝试注入EntityManagerFactory,然后手动创建EntityManager:

代码语言:javascript
复制
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;

public boolean processBills() throws Exception{

   EntityManager em = entityManagerFactory.createEntityManager();

   EntityTransaction tx = null;

   Session session = null;

   try{

       session = em.unwrap(Session.class);
       tx = em.getTransaction();
票数 7
EN

Stack Overflow用户

发布于 2017-03-20 19:04:22

@PersistenceContext返回的EntityManager实例始终是容器管理的EntityManager。容器管理的EntityManager总是JTA EntityManagers,因此它们的生命周期是由容器管理的。我想现在可以理解为什么对它们调用getTransaction()是非法的了。This might help

票数 1
EN

Stack Overflow用户

发布于 2017-03-20 21:48:34

添加值为truehibernate.jta.allowTransactionAccess属性,应该允许您手动使用它。尽管混合策略并不是一种好的做法,但让一些代码由JTA管理,一些代码是手动管理的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42900265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档