当懒惰加载时,Spring @Transactional无法正常工作

时间:2014-11-23 17:07:11

标签: java spring jpa transactions lazy-loading

我正在处理一个处理书店的小型maven(多模块)项目。

我在懒惰加载实体集合时遇到问题

用户拥有一系列延迟加载的订单。

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: edu.flst.bookstore.domaine.bo.User.orders, could not initialize proxy - no Session
org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:137)
org.hibernate.collection.internal.PersistentBag.size(PersistentBag.java:242)
org.dozer.MappingProcessor.prepareDestinationList(MappingProcessor.java:881)
org.dozer.MappingProcessor.addOrUpdateToList(MappingProcessor.java:806)
org.dozer.MappingProcessor.addOrUpdateToList(MappingProcessor.java:894)
org.dozer.MappingProcessor.mapListToList(MappingProcessor.java:730)
org.dozer.MappingProcessor.mapCollection(MappingProcessor.java:580)
org.dozer.MappingProcessor.mapOrRecurseObject(MappingProcessor.java:453)
org.dozer.MappingProcessor.mapFromFieldMap(MappingProcessor.java:361)
org.dozer.MappingProcessor.mapField(MappingProcessor.java:307)
org.dozer.MappingProcessor.map(MappingProcessor.java:267)
org.dozer.MappingProcessor.mapToDestObject(MappingProcessor.java:216)
org.dozer.MappingProcessor.createByCreationDirectiveAndMap(MappingProcessor.java:196)
org.dozer.MappingProcessor.mapGeneral(MappingProcessor.java:170)
org.dozer.MappingProcessor.map(MappingProcessor.java:104)
org.dozer.MappingProcessor.map(MappingProcessor.java:99)
org.dozer.DozerBeanMapper.map(DozerBeanMapper.java:120)
edu.flst.bookstore.transverse.utils.mapper.MapperUtils.map(MapperUtils.java:30)
edu.flst.bookstore.service.impl.UserServiceImpl.rechercher(UserServiceImpl.java:26)
edu.flst.bookstore.presentation.controller.HomeController.index(HomeController.java:20)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)

我目前正在使用Tomcat,因此我无法添加JTA交易。

我使用Spring的JPA事务管理器来处理事务。

<!-- ============================= -->
<!-- TRANSACTION MANAGER           -->
<!-- ============================= -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

bean位于我的持久层spring上下文文件中。

我已将@Transactional注释添加到我的抽象服务中(我的所有服务都扩展了此类)

@Service
@Transactional
public abstract class AbstractServiceImpl {

    @Autowired protected UserRepository userRepository;

    @Autowired protected OrderRepository orderRepository;

    @Autowired protected BookRepository bookRepository;

    @Autowired protected Mapper mapperService;

}

它实际上并不起作用。我尝试在我的存储库界面中设置注释(我使用的是Spring数据JPA),但它也不起作用。

1 个答案:

答案 0 :(得分:0)

如果您检索包含延迟引用的实体并且在您已经离开事务上下文时第一次取消引用此实例,则通常会出现此问题。由于未从数据库中检索到引用,因此无法取消引用。 AFAIK有三个解决这个问题的方法:

  • 使用渴望获取从数据库中获取所有内容
  • 在数据库访问层中获取必要的延迟引用以使其可用
  • 使用即使在实际数据库访问层之后保持打开的持久性事务