4

大家好,我花了相当多的时间谷歌搜索并从 JSON 1 升级到 JSON 2,但是当我尝试返回实体列表时,我得到了异常:

“收到的异常无法写入 JSON:无法初始化代理 - 没有会话(通过引用链:”

我知道这与 Hibernate 惰性初始化有关,但我还没有弄清楚如何解决它。我认为 jackson-module-hibernate 项目是解决方案。但是我无法让它工作。

这是我的技术:

  • 春季:3.2.1发布
  • 休眠 4.1.7.Final
  • 杰克逊 2
  • 杰克逊核心 2.0.4
  • 杰克逊数据绑定:2.0.4
  • 杰克逊数据类型休眠4:2.1.2

我正在使用 Java 配置:...

@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);
}
}

流程从控制器开始,控制器调用多个服务,每个服务都返回一个实体或列表。然后我将返回的对象放入一个对象中并返回它,认为@ResponseBody 会起作用。但是,我一定不能正确连接,因为我仍然会遇到异常。

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

谢天谢地...

4

2 回答 2

3

这在 jackson-datatype-hibernate 的 2.5.0 版本中得到解决。只需在 Hibernate(3,4)Module 中传递 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 模式。

于 2015-02-05T10:14:57.577 回答
0

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

当执行存在事务时,用于加载对象的休眠会话将关闭,因此当视图层(杰克逊)尝试序列化对象并尝试加载延迟加载的对象时,它会失败并出现此错误。

在你的 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>
于 2013-03-15T04:07:05.120 回答