[SPRING] entityManager를 사용하여 JPA에서 트랜잭션을 시작하는 방법
SPRINGentityManager를 사용하여 JPA에서 트랜잭션을 시작하는 방법
Spring, Hibernate, JPA, SOAP 웹 서비스를 사용하는 응용 프로그램에 대한 작업을 시작했습니다. 이제 특정 쿼리를 트랜잭션에서 실행해야한다는 요구 사항이 있습니다. 하나라도 실패하면 전체 트랜잭션이 롤백됩니다.
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의 트랜잭션으로 대체하려고합니다. 그럼 어떻게해야합니까?
해결법
-
==============================
1.EntityManagerFactory를 삽입 한 다음 EntityManager를 수동으로 생성 해보십시오.
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();
-
==============================
2.@PersistenceContext에 의해 반환 된 EntityManager 인스턴스는 항상 컨테이너로 관리되는 EntityManager입니다. 컨테이너 관리 EntityManager는 항상 JTA EntityManager이므로 컨테이너의 라이프 사이클을 관리합니다. 이제 getTransaction ()을 호출하는 것이 불법 인 이유에 대해 이해할 수 있습니다. 그러면 도움이 될 것입니다.
@PersistenceContext에 의해 반환 된 EntityManager 인스턴스는 항상 컨테이너로 관리되는 EntityManager입니다. 컨테이너 관리 EntityManager는 항상 JTA EntityManager이므로 컨테이너의 라이프 사이클을 관리합니다. 이제 getTransaction ()을 호출하는 것이 불법 인 이유에 대해 이해할 수 있습니다. 그러면 도움이 될 것입니다.
-
==============================
3.@ 트랜잭션 주석은 사용자가 필요로하는 것을 정확하게 수행합니다.
@ 트랜잭션 주석은 사용자가 필요로하는 것을 정확하게 수행합니다.
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html#transaction-declarative-annotations
-
==============================
4.값이 true 인 hibernate.jta.allowTransactionAccess 속성을 추가하면 수동으로 사용할 수 있어야합니다. JTA가 관리하는 일부 코드를 수동으로 사용하는 전략을 혼합하는 것은 좋지 않습니다.
값이 true 인 hibernate.jta.allowTransactionAccess 속성을 추가하면 수동으로 사용할 수 있어야합니다. JTA가 관리하는 일부 코드를 수동으로 사용하는 전략을 혼합하는 것은 좋지 않습니다.
from https://stackoverflow.com/questions/42900265/how-to-start-a-transaction-in-jpa-using-entitymanager by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] @Document가있는 몽고 멀티 입주 (0) | 2019.03.31 |
---|---|
[SPRING] Spring LdapAuthentication 및 로컬 데이터베이스에서 롤로드 (0) | 2019.03.31 |
[SPRING] Spring에서는 autowired bean 내부에서 새로운 bean을 autowire 할 수 있습니까? (0) | 2019.03.31 |
[SPRING] JPA에서 사용자 정의 ID 생성 방법 (0) | 2019.03.31 |
[SPRING] Spring Framework 필터, 빈이 주입되지 않음 (0) | 2019.03.31 |