[SPRING] 스프링 부트 최대 절전 모드 트랜잭션 없음
SPRING스프링 부트 최대 절전 모드 트랜잭션 없음
나는 봄 부팅을 사용하고 있으며 완벽하게 엔티티 관리자가되었습니다. 그리고 엔티티 관리자로부터 세션 팩토리를 테스트하고 예제로 사용하기로 결정했습니다. 하지만 다음 문제가 발생합니다 : javax.persistence.TransactionRequiredException : 트랜잭션이 진행되고 있지 않습니다.
속성들
spring.datasource.url= jdbc:postgresql://localhost:5432/ring
spring.datasource.username=postgres
spring.datasource.password=root
spring.jpa.show-sql = false
spring.jpa.properties.hibernate.format_sql=false
#Note: The last two properties on the code snippet above were added to suppress an annoying exception
# that occurs when JPA (Hibernate) tries to verify PostgreSQL CLOB feature.
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.jpa.properties.hibernate.current_session_context_class = org.springframework.orm.hibernate5.SpringSessionContext
서비스 클래스
package kz.training.springrest.service;
import kz.training.springrest.entity.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
@Service
public class UserService {
@PersistenceContext
private EntityManager entityManager;
@Transactional
public void insertUser(User user) {
SessionFactory sessionFactory = entityManager.unwrap(Session.class).getSessionFactory();
Session session = sessionFactory.getCurrentSession();
session.save(user);
}
}
달리는 사람
package kz.training.springrest.run;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EntityScan("kz.training.springrest.entity")
@EnableTransactionManagement
@ComponentScan(basePackages="kz.training.springrest")
public class SpringrestApplication {
public static void main(String[] args) {
SpringApplication.run(SpringrestApplication.class, args);
}
}
어떻게 해결할 수있는 아이디어가 있습니까?
해결법
-
==============================
1.서비스 방법이 불필요하게 복잡 해지는 이유를 잘 모르겠습니다. 당신은이 방법으로 간단하게 할 수 있어야합니다.
서비스 방법이 불필요하게 복잡 해지는 이유를 잘 모르겠습니다. 당신은이 방법으로 간단하게 할 수 있어야합니다.
@Transactional public void insertUser(User user) { entityManager.persist( user ); }
네이티브 Hibernate Session에 대한 액세스가 필요한 지점이 있으면 다음과 같이 세션을 간단히 풀고 사용할 수 있습니다.
@Transactional public void doSomethingFancyWithASession() { Session session = entityManager.unwrap( Session.class ); // use session as needed }
여기서 Spring은 @PersistenceContext 어노테이션을 사용하여 Spring이 이미 기능하는 EntityManager 인스턴스를 제공한다는 것이다. 이 인스턴스는 스프링 bean이 실행되는 현재 스레드에 의해 안전하게 사용할 수 있습니다.
둘째, @Transactional을 사용하면 Spring의 트랜잭션 관리가 EntityManager가 트랜잭션에 바인딩되었는지 여부를 자동으로 확인하게됩니다. RESOURCE_LOCAL 또는 JTA 트랜잭션이 환경 구성을 기반으로합니다.
#getCurrentSession () 호출로 인해 문제가 발생했습니다.
Spring은 EntityManager를 생성하고, #getCurrentSession ()을 호출 할 때 메소드 내부에서 @Transactional 어노테이션에 의해 시작된 트랜잭션에 바인딩되지 않은 두 번째 세션을 생성하도록 Hibernate에 요청합니다. 간단히 요약하면 다음과 같습니다.
EntityManager entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); Session aNewSession = entityManager.unwrap( Session.class ) .getFactory() .getCurrentSession(); // at this point entityManager is scoped to a transaction // aNewSession is not scoped to any transaction // this also likely uses 2 connections to the database which is a waste
위에서 언급 한 패러다임을 따라 가면 더 이상 문제가 발생하지 않아야합니다. Spring 환경에서 EntityManager 인스턴스를 적절하게 삽입 할 수있게하려면 Spring 환경에서 #getCurrentSession () 또는 #openSession ()을 호출 할 필요가 없다.
-
==============================
2.스프링 부트 응용 프로그램을 WebLogic Server에 배포 할 때도 동일한 오류가 발생합니다. (심지어 Eclipse (Tomcat에 배포)를 통해 직접 실행하는 경우에도 작동합니다.)
스프링 부트 응용 프로그램을 WebLogic Server에 배포 할 때도 동일한 오류가 발생합니다. (심지어 Eclipse (Tomcat에 배포)를 통해 직접 실행하는 경우에도 작동합니다.)
UserService에 @EnableTransactionManagement를 추가하여 문제를 해결했습니다.
from https://stackoverflow.com/questions/50650041/spring-boot-hibernate-no-transaction-is-in-progress by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 프로파일 변수 설정하기 (0) | 2019.05.02 |
---|---|
[SPRING] @DecimalMin 및 @DecimalMax를 사용하여 List <BigDecimal>의 유효성을 검사하는 방법 (0) | 2019.05.02 |
[SPRING] 최대 절전 모드 + 봄 응용 프로그램에서 mysql으로 csv 파일을 가져 오는 방법은 무엇입니까? (0) | 2019.05.02 |
[SPRING] 스프링 부트의 임베디드 바람둥이 전쟁을 어떻게 확장 할 것인가? (0) | 2019.05.02 |
[SPRING] 스프링 csrf 토큰 변수의 이름 바꾸기 (0) | 2019.05.02 |