web-dev-qa-db-ja.com

entityManagerを使用してJPAでトランザクションを開始する方法

Spring、hibernate、JPA、SOAP webservices。を使用するアプリケーションで作業を開始しました。現在、特定のクエリをトランザクションで実行する必要があります。ロールバックする必要があります。

Daoレイヤーのコードは次のとおりです。

_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()を実行すると、次のエラーが発生します。

_Java.lang.IllegalStateException: Cannot execute getTransaction() on a container-managed EntityManager
_

その他のトランザクション関連のプロパティは次のとおりです。

_<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からのトランザクションに置き換えたいと思います。次に、何をすべきですか?

5
azaveri7

EntityManagerFactoryを注入してから、EntityManagerを手動で作成してみてください。

@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();
6
Maciej Kowalski

@PersistenceContextによって返されるEntityManagerインスタンスは、常にコンテナ管理のEntityManagerです。また、コンテナ管理のEntityManagerは常にJTA EntityManagerであるため、そのライフサイクルはコンテナによって管理されます。なぜそれらに対してgetTransaction()を呼び出すのが違法であるのかが理にかなっていると思います。 これが役立つかもしれません

1
userJ
0
yaswanth

trueを持つhibernate.jta.allowTransactionAccessプロパティを追加すると、手動で使用できるようになります。戦略を混ぜて、JTAが管理するコードと手動で管理するコードを混在させることはお勧めできません。

0
coladict