Spring LazyInitializationException使用" redirect"在控制器中

时间:2015-05-27 14:13:58

标签: spring-mvc spring-security spring-roo

我开始使用Spring-Roo 1.3.1和Spring-Security 3.1.7

创建一个应用程序

我使用Spring OpenEntityManagerInViewFilter能够延迟加载我的域对象。

<filter>
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

到目前为止,此工作正常。但是,从控制器执行重定向时遇到以下问题:

@RequestMapping(method = RequestMethod.PUT, produces = "text/html")
public String update(@Valid Service service, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest) {
    if (bindingResult.hasErrors()) {
        populateEditForm(uiModel, service);
        return "services/update";
    }
    uiModel.asMap().clear();
    serviceRepository.save(service);
    return "redirect:/services/" + encodeUrlPathSegment(service.getId().toString(), httpServletRequest);
}

此重定向return "redirect:/services/" + encodeUrlPathSegment(service.getId().toString(), httpServletRequest);失败并显示LazyInitializationException。在提交完成并重定向发生后,在执行过滤器链期间失败。重定向到的URL在直接访问时正在工作。

使用return "forward:/services/" + encodeUrlPathSegment(service.getId().toString(), httpServletRequest);时,页面加载就好了。

我真的不知道为什么在使用&#34; redirect&#34;时hibernate会话不可用。另一个奇怪的事情是,当激活org.springframework.security.web的DEBUG日志记录时,工作正常。

e.g。 log4j.logger.org.springframework.security.web=DEBUG

我已经在互联网上搜索了一些提示,但一般来说懒人加载在我的应用程序中工作正常,只是在那种情况下,目前我还不完全理解为什么。

欢迎任何评论/提示。

由于 斯蒂芬

1 个答案:

答案 0 :(得分:0)

尝试更改控制器:

@RequestMapping(method = RequestMethod.PUT, produces = "text/html")
public String update(@Valid Service service, BindingResult bindingResult, 
           Model uiModel, HttpServletRequest httpServletRequest) {
      if (bindingResult.hasErrors()) {
          populateEditForm(uiModel, service);
          return "services/update";
      }
      uiModel.asMap().clear();
      Service attached = serviceRepository.save(service);
      return "redirect:/services/" +
           encodeUrlPathSegment(attached.getId().toString(),
           httpServletRequest);
}

实例service由Spring绑定器创建,用于将请求值映射到对象,但它不附加到entityManager(无数据库会话)。当你调用save时,你得到一个attached(由entityManager管理的实例)实例,所以,如果你试图从这个实例获取任何延迟属性,它就知道它是怎么做的。

您可以找到有关JPA对象实时周期here的更多信息。

祝你好运!