[SPRING] @Transactional 주석이있는 Spring OpenSessionInViewFilter
SPRING@Transactional 주석이있는 Spring OpenSessionInViewFilter
이것은 서비스 레이어에서 @Transactional 주석을 사용하여 Spring OpenSessionInViewFilter에 관한 것입니다.
이 너무 많은 스택 오버플로 게시물을 통해 갔다하지만 여전히 OpenSessionInViewFilter 또는 LazyInitializationException 않도록하려면 사용해야하는지 혼란에 대해 혼란 스러워요. 누군가 아래의 질문에 대한 답변을 찾도록 도와 주면 큰 도움이 될 것입니다.
아래는 나의 Spring 설정 파일이다.
<context:component-scan base-package="com.test"/>
<context:annotation-config/>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="resources/messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<!--
<prop key="hibernate.hbm2ddl.auto">create</prop>
-->
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
해결법
-
==============================
1.OpenSessionInView는 최대 절전 모드 세션을 열고 요청을 처리하는 스레드의 SessionHolder에 저장하는 것보다 서블릿 필터입니다. 이 세션이 열리면, hibernate는 요청의 렌더링 단계에서 이것을 사용할 때 Lazy 초기화 된 콜렉션과 객체를 읽을 수있다. 이 세션은 SessionFactory.getCurrentSession ()을 호출 할 때 액세스 할 수 있습니다.
OpenSessionInView는 최대 절전 모드 세션을 열고 요청을 처리하는 스레드의 SessionHolder에 저장하는 것보다 서블릿 필터입니다. 이 세션이 열리면, hibernate는 요청의 렌더링 단계에서 이것을 사용할 때 Lazy 초기화 된 콜렉션과 객체를 읽을 수있다. 이 세션은 SessionFactory.getCurrentSession ()을 호출 할 때 액세스 할 수 있습니다.
그러나 OpenSessionInView는 세션을 열뿐 트랜잭션을 시작하지 않습니다. 세션이 열리면 데이터베이스에서 객체를 읽을 수 있지만, 트랜잭션에서 무언가를하고 싶다면 @Transactional 어노테이션이나 원할 때 트랜잭션의 시작과 끝을 구별하는 다른 메커니즘이 필요합니다.
그런 다음 질문의 대답 :
이것은 LazyInitializationException을 피할 필요가 있고 과부하가 단지 새로운 Hibernate Session을 열고 각 요청에 대한 요청의 끝에서 그것을 닫을 때 좋은 연습이다.
나는 많은 프로젝트에서이 필터를 사용하고 어떤 문제도 일으키지 않습니다.
아닙니다. SessionHolder에서 열어 놓은 Hibernate Session 만 있습니다. 그러나 Transaction이 필요하다면 @Transactional을 넣어야합니다.
-
==============================
2.내 0.02c 여기에 던져 (그리고 페르난도 Rincon의 훌륭한 답변 확대) :
내 0.02c 여기에 던져 (그리고 페르난도 Rincon의 훌륭한 답변 확대) :
LazyInitializationException을 피해야하기 때문에 OpenSessionInView 필터를 사용하면 안됩니다. 시스템에 혼란과 복잡성을 추가 할 것입니다. 프론트 엔드에서 콜렉션에 액세스해야하는 위치를 시스템 설계에서 정확히 알아야합니다. 거기에서, (내 경험상) 콜렉션을 검색하기 위해 서비스 메소드를 호출하는 컨트롤러 메소드를 만드는 것이 더 쉽다.
그러나 OpenSessionInView 필터를 사용하여 해결할 수있는 또 다른 문제가 생기면 부작용으로 세션을 연다. 그런 다음 세션을 열어서 콜렉션에 액세스 할 때 해를 입지 않는다. 그러나 OpenSessionInView를 사용하여 한 위치에서 컬렉션 객체를 가져 오는 경우 다른 위치에서 코드를 리팩터링하여 컬렉션을 가져 오는 데 사용 된 전략이 응용 프로그램에서 표준화되도록해야합니다.
OpenSessionInView 필터를 사용해야하는지 결정하기 위해 컨트롤러 및 서비스 메소드를 작성하는 비용과 비교하여이 리팩터의 비용을 비쌉니다.
-
==============================
3.OpenSessionInViewFilter는 http 요청에 대한 최대 절전 모드 세션을 바인드하는 서블릿 필터이며 모든 HTTP 요청에 대해 트랜잭션 및 비 트랜잭션 모드의 동일한 최대 절전 모드 세션이 사용됩니다. 이렇게하면 db 레이어가 웹 레이어에 노출되어 안티 패턴이됩니다.
OpenSessionInViewFilter는 http 요청에 대한 최대 절전 모드 세션을 바인드하는 서블릿 필터이며 모든 HTTP 요청에 대해 트랜잭션 및 비 트랜잭션 모드의 동일한 최대 절전 모드 세션이 사용됩니다. 이렇게하면 db 레이어가 웹 레이어에 노출되어 안티 패턴이됩니다.
내 경험에 의하면 자바 객체를 변경하고자 할 때 코드를 디버그하기가 어렵고, 자바 객체가 데이터베이스에 반영되는 것을 원하지 않는다. 최대 절전 모드 세션은 항상 열려 있기 때문에 데이터베이스의 데이터를 플러시 할 것으로 예상됩니다.
이것은 JS 기본 휴식 서비스가 중간에 서비스 레이어가없는 경우에만 사용해야합니다.
-
==============================
4.OpenSessionInViewFilter의 일반적인 사용 패턴은 일부 Entity가 느리게로드되지만 뷰 렌더링 단계에서 뷰가이 엔터티의 일부 특성을 필요로하므로 초기에로드되지 않았으므로 데이터베이스에서이 데이터를 가져올 필요가 있습니다. 이제는 일반적으로 트랜잭션 경계 설정이 웹 애플리케이션의 서비스 계층에서 이루어 지므로 뷰 렌더링이 수행 될 때까지 뷰가 분리 된 엔티티와 함께 작동하여 언로드 된 속성에 액세스 할 때 LazyInitializationException이 발생합니다.
OpenSessionInViewFilter의 일반적인 사용 패턴은 일부 Entity가 느리게로드되지만 뷰 렌더링 단계에서 뷰가이 엔터티의 일부 특성을 필요로하므로 초기에로드되지 않았으므로 데이터베이스에서이 데이터를 가져올 필요가 있습니다. 이제는 일반적으로 트랜잭션 경계 설정이 웹 애플리케이션의 서비스 계층에서 이루어 지므로 뷰 렌더링이 수행 될 때까지 뷰가 분리 된 엔티티와 함께 작동하여 언로드 된 속성에 액세스 할 때 LazyInitializationException이 발생합니다.
이 URL https://developer.jboss.org/wiki/OpenSessionInView에서 :
또는보기에 필요한 양의 데이터만으로 엔티티를로드하는 것을 고려해보십시오. 이것은 DTO 예측을 사용하여 수행 할 수 있습니다. 이 기사에서는 View Session In View 패턴을 사용할 때의 단점을 나열합니다. https://vladmihalcea.com/the-open-session-in-view-anti-pattern/
from https://stackoverflow.com/questions/23877900/spring-opensessioninviewfilter-with-transactional-annotation by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Data JPA - 구성에 'entityManagerFactory'라는 bean 정의를 고려하십시오. (0) | 2019.03.20 |
---|---|
[SPRING] Thymeleaf로 Javascript 함수 호출 (0) | 2019.03.20 |
[SPRING] POM에서 응용 프로그램 버전 가져 오기 (0) | 2019.03.20 |
[SPRING] RESTful 게시물 데이터를 어떻게 기록합니까? (0) | 2019.03.20 |
[SPRING] 도트를위한 JsonPath JUnit 이스케이프 문자 (0) | 2019.03.20 |