无法初始化代理 - 没有会话

时间:2013-03-15 04:04:53

标签: json spring hibernate jackson

美好的一天, 我花了相当多的时间Googlin'并从JSON 1升级到JSON 2但是当我尝试返回一个实体列表时,我得到了例外:

“收到异常无法写入JSON:无法初始化代理 - 无会话(通过参考链:”

我知道这与Hibernate lazy init有关,但我还没弄清楚如何修复它。我认为jackson-module-hibernate项目是解决方案。但是我无法使它发挥作用。

这是我的技术:

  • Spring:3.2.1RELEASE
  • Hibernate 4.1.7.Final
  • Jackson 2
  • jackson-core 2.0.4
  • jackson-databind:2.0.4
  • jackson-datatype-hibernate4:2.1.2

我正在使用Java Config:  ...

@Bean
public com.mycompany.config.MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
    mappingJackson2HttpMessageConverter.setObjectMapper(new HibernateAwareObjectMapper());
    return mappingJackson2HttpMessageConverter;
}

@Bean 
public OpenEntityManagerInViewFilter springOpenEntityManagerInViewFilter() {
return new org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter();
}

@Bean
public ContentNegotiatingViewResolver contentNegotiatingViewResolver() {
final ContentNegotiatingViewResolver contentNegotiatingViewResolver = new ContentNegotiatingViewResolver();
contentNegotiatingViewResolver.setDefaultContentType(MediaType.APPLICATION_JSON);
final ArrayList defaultViews = new ArrayList();
defaultViews.add(converter());
contentNegotiatingViewResolver.setDefaultViews(defaultViews);
   return contentNegotiatingViewResolver;
}

我也有:

public class HibernateAwareObjectMapper extends ObjectMapper {

public HibernateAwareObjectMapper() {
    Hibernate4Module hm = new Hibernate4Module();
    registerModule(hm);
}
}

流程从控制器开始,控制器调用多个服务,每个服务返回一个实体或List。然后我将返回的对象放入一个对象并返回它,认为@ResponseBody将起作用。但是,由于我仍然有例外,所以我不能把事情连接起来。

有人可以在这看到任何错误吗?

...感激

2 个答案:

答案 0 :(得分:3)

这是在jackson-datatype-hibernate的2.5.0版本中解决的。只需在Hibernate(3,4)模块中传递Hibernate SessionFactory,如下所示:

public class HibernateAwareObjectMapper extends ObjectMapper {

private static final long serialVersionUID = 1L;

@Autowired
private EntityManagerFactory emf;

@PostConstruct
public void init() {
    Hibernate4Module module = new Hibernate4Module(emf.unwrap(SessionFactory.class));

    module.enable(Hibernate4Module.Feature.FORCE_LAZY_LOADING);
    module.disable(Hibernate4Module.Feature.USE_TRANSIENT_ANNOTATION);
}}

如果正在使用JPA,则上面的代码段很好,因此可以使用EntityManagerFactory bean。否则,只需注入Hibernate SessionFactory并传递给构造函数。

无需使用OpenSessionInView模式。

答案 1 :(得分:0)

这是因为您尝试序列化的对象具有延迟加载的组件,您可以将OpenSessionInViewFilter添加到Web配置中以解决此问题。

当执行存在事务时,用于加载对象的hibernate会话将被关闭,因此当视图层(jackson)尝试序列化对象并尝试加载延迟加载的对象时,它会因此错误而失败。

在web.xml中添加

<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>/app/*</url-pattern>
</filter-mapping>