[SPRING] HibernateException : 현재 스레드에 대해 트랜잭션 동기화 세션을 가져올 수 없습니다.
SPRINGHibernateException : 현재 스레드에 대해 트랜잭션 동기화 세션을 가져올 수 없습니다.
내 @Service 주석이 달린 클래스를 사용하려고 할 때 다음과 같은 예외가 발생합니다.
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134) ~[spring-orm-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014) ~[hibernate-core-4.3.6.Final.jar:4.3.6.Final]
at webapp.base.repository.GenericDaoImpl.saveOrUpdate(GenericDaoImpl.java:59) ~[base-0.0.1-SNAPSHOT-classes.jar:na]
at com.example.repository.PageViewDaoImpl.saveOrUpdate(PageViewDaoImpl.java:19) ~[site-0.0.1-SNAPSHOT.jar:na]
at com.example.repository.PageViewDaoImpl.saveOrUpdate(PageViewDaoImpl.java:14) ~[site-0.0.1-SNAPSHOT.jar:na]
at com.example.service.PageViewServiceImpl.savePageView(PageViewServiceImpl.java:26) ~[site-0.0.1-SNAPSHOT.jar:na]
at com.example.interceptor.PageViewInterceptor.preHandle(PageViewInterceptor.java:29) ~[site-0.0.1-SNAPSHOT.jar:na]
at org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:130) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620) [servlet-api-3.0.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [servlet-api-3.0.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:488) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:411) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:466) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:337) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:427) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:200) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) [tomcat-catalina-7.0.52.jar:7.0.52]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) [tomcat-coyote-7.0.52.jar:7.0.52]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) [tomcat-coyote-7.0.52.jar:7.0.52]
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313) [tomcat-coyote-7.0.52.jar:7.0.52]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_65]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_65]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_65]
애플리케이션을 초기화하는 방법은 복잡하므로 https://github.com/dtrunk90/webapp-base와 같은 추가 정보를 얻으려면 전체 기본 코드에 대한 링크를 제공해야합니다. 저는 이것을 Maven 오버레이로 사용하고 있습니다.
다음은 필요한 코드입니다.
Initializer (webapp-base에서) :
public abstract class AbstractWebApplicationInitializer extends AbstractDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[] {"/*"};
}
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
encodingFilter.setEncoding("UTF-8");
encodingFilter.setForceEncoding(true);
return new Filter[] {encodingFilter};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
ConfigurableEnvironment environment = rootContext.getEnvironment();
environment.setDefaultProfiles("production");
PropertyUtil propertyUtil = PropertyUtil.getInstance(environment.getActiveProfiles());
String[] basePackages = propertyUtil.getPropertySplitTrimmed("webapp", "basePackages");
rootContext.scan(basePackages);
return rootContext;
}
@Override
protected WebApplicationContext createServletApplicationContext() {
return new AnnotationConfigWebApplicationContext();
}
}
Initializer (내 webapp에서) :
public class WebApplicationInitializer extends AbstractWebApplicationInitializer {
}
@Configuration (webapp-base에서) :
@Configuration
@EnableTransactionManagement
public class TransactionConfiguration {
@Bean
public DataSource dataSource() throws IOException {
Properties conProps = PropertyUtil.getInstance().getProperties("jdbc");
if (conProps.containsKey("url")) {
DriverManagerDataSource dataSource = new DriverManagerDataSource(conProps.getProperty("url"), conProps);
dataSource.setDriverClassName(conProps.getProperty("driverClassName"));
return dataSource;
}
return null;
}
@Bean
public SessionFactory sessionFactory() throws IOException {
DataSource dataSource = dataSource();
if (dataSource != null) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.scanPackages(PropertyUtil.getInstance().getPropertySplitTrimmed("hibernate", "packagesToScan"));
sessionBuilder.addProperties(PropertyUtil.getInstance().getProperties("hibernate"));
return sessionBuilder.buildSessionFactory();
}
return null;
}
@Bean
public HibernateTransactionManager transactionManager() throws IOException {
SessionFactory sessionFactory = sessionFactory();
if (sessionFactory == null) {
return null;
}
return new HibernateTransactionManager(sessionFactory);
}
}
@Configuration (내 webapp에서) :
@Configuration
public class MainConfiguration extends WebMvcConfigurerAdapter {
@Autowired
private PageViewInterceptor pageViewInterceptor; // Is annotated with @Component
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(pageViewInterceptor);
}
}
@서비스:
@Service
public class PageViewServiceImpl implements PageViewService {
@Autowired
private PageViewDao pageViewDao;
@Override
public void savePageView(long ip, String visitPage, String userAgent) {
PageView obj = new PageView();
obj.setVisitDate(new Date());
obj.setUserAgent(userAgent);
obj.setPage(visitPage);
obj.setIp(ip);
pageViewDao.saveOrUpdate(obj);
}
}
@저장소:
@Repository
public class PageViewDaoImpl extends GenericDaoImpl<PageView, Long> implements PageViewDao {
@Override
public void saveOrUpdate(PageView obj) {
if (!obj.isBot()) {
super.saveOrUpdate(obj);
}
}
}
public abstract class GenericDaoImpl<T extends Identifier<I>, I extends Serializable> implements GenericDao<T, I> {
@Autowired
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
if (sessionFactory == null) {
throw new IllegalStateException("SessionFactory has not been set on DAO before usage");
}
return sessionFactory;
}
@Transactional
public void saveOrUpdate(T obj) {
getSessionFactory().getCurrentSession().saveOrUpdate(obj);
}
}
그런 다음 PageViewService를 autowiring하고 해당 메소드를 사용합니다.
같은 문제가있는 몇 가지 질문이 있지만 이미 확인했습니다.
현재 스레드에 대해 트랜잭션 동기화 세션을 가져올 수 없습니다.
HibernateException : 현재 스레드에 대해 트랜잭션 동기화 세션을 가져올 수 없습니다.
Spring Hibernate - 현재 스레드에 대한 트랜잭션 동기화 세션을 가져올 수 없음
org.hibernate.HibernateException : 현재 스레드에 대한 트랜잭션 동기화 세션을 가져올 수 없습니다.
해결법
-
==============================
1.로그를 보면 트랜잭션 설정이 잘못 설정되었다는 것을 즉시 알 수 있습니다. 그것은 스택 추적에 TransactionInterceptor 호출이 없기 때문입니다.
로그를 보면 트랜잭션 설정이 잘못 설정되었다는 것을 즉시 알 수 있습니다. 그것은 스택 추적에 TransactionInterceptor 호출이 없기 때문입니다.
TransactionInterceptor는 웹 컨트롤러가 실제 Service 메소드를 호출 할 때 스프링 서비스 프록시에 의해 호출된다.
-
==============================
2.하나
하나
@Service 및 @Repository에는 @Transactional을 사용해야합니다. Spring은 트랜잭션 지원으로 프록시를 적용하고 생성 할 수 있습니다.
코드에서 @Service 클래스에는 클래스 수준 또는 메서드 수준에서 @Transacional이 없습니다.
둘째
WebApplicationInitializer를 구현하는 클래스는 어디에 있습니까? 어쨌든 내 포인트는 다음과 같습니다.
@Override public void onStartup(ServletContext container) { // Create the 'root' Spring application context AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(CentralServerConfigurationEntryPoint.class); // Manage the lifecycle of the root application context container.addListener(new ContextLoaderListener(rootContext)); // Create the dispatcher servlet's Spring application context AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext(); dispatcherServlet.register(CentralWebConfigurationEntryPoint.class); // Register and map the dispatcher servlet ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); }
CentralServerConfigurationEntryPoint.class는 서버 측 (@Service, @Repository, @Configuration for Transaction, Hibernate, DataSource 등)에서 작동해야하는 구성 요소 만 검색해야합니다.
CentralWebConfigurationEntryPoint는 클라이언트 / 웹 측 (@Controller, @Configuration for Formtersters, Tiles, Converters 등)에서 작동해야하는 구성 요소 만 검색해야합니다.
나는 당신의 코드에 대해 이해하지 못한다.
@Override protected WebApplicationContext createRootApplicationContext() { AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); ConfigurableEnvironment environment = rootContext.getEnvironment(); environment.setDefaultProfiles("production"); PropertyUtil propertyUtil = PropertyUtil.getInstance(environment.getActiveProfiles()); String[] basePackages = propertyUtil.getPropertySplitTrimmed("webapp", "basePackages"); rootContext.scan(basePackages); return rootContext; } @Override protected WebApplicationContext createServletApplicationContext() { return new AnnotationConfigWebApplicationContext(); }
내 요점은 : 당신은 두 개의 AnnotationConfigWebApplicationContext 서버와 웹쪽에 하나 있어야합니다.
-
==============================
3.이 질문에 대한 간단한 대답은 id 클래스입니다. @Transactional을 DAO 클래스와 함께 사용하고, 구성 클래스를 @EnableTransactionManagement로 표시하고 bean을 생성해야합니다.
이 질문에 대한 간단한 대답은 id 클래스입니다. @Transactional을 DAO 클래스와 함께 사용하고, 구성 클래스를 @EnableTransactionManagement로 표시하고 bean을 생성해야합니다.
**@Bean public PlatformTransactionManager transactionManager() { DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource()); return transactionManager; }**
여기에서 EnableTransactionManagement 주석에서 사용할 수있는 코드 예제를 보면 HibernateTransactionManager 대신 DataSourceTransactionManager를 사용하는 것이 좋습니다.
from https://stackoverflow.com/questions/26562787/hibernateexception-couldnt-obtain-transaction-synchronized-session-for-current by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 프로세스 봄 부팅 외부화 된 속성 값 (0) | 2018.12.26 |
---|---|
[SPRING] 프리 플라이트에 대한 응답에 잘못된 HTTP 상태 코드 401이 있습니다. (0) | 2018.12.26 |
[SPRING] java.lang.IllegalStateException : 사용할 수있는 트랜잭션 가능한 EntityManager가 없습니다. (0) | 2018.12.26 |
[SPRING] java.lang.NoSuchMethodError : 자바 스크립트 숨겨진 기능은 무엇입니까? (0) | 2018.12.26 |
[SPRING] Spring 빈을 비 프로비저닝 할 수 있습니까? (0) | 2018.12.26 |