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

4

大家好, 我花了很多时间在Google上搜索,并从JSON 1升级到JSON 2,但当我尝试返回一个实体列表时,出现异常:

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

我知道这与Hibernate懒加载有关,但我还没有找到解决方法。我认为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);
}
}

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

有人能看出这里有什么错误吗?

感激不尽...

2个回答

3
这个问题已经在 jackson-datatype-hibernate 的 2.5.0 版本中解决。只需按照以下方式将 Hibernate SessionFactory 传递给 Hibernate(3,4)Module 模块即可:
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模式。

太棒了。可以在hibernate 4、jpa 2.0和datatype 2.6.0上运行。但是,你应该使用EntityManager.unwrap(HibernateEntityManager.class).getSession().getSessionFactory()而不是emf.unwrap,因为emf.unwrap仅适用于jpa 2.1(尽管我没有检查过)。 - Vadim Kirilchuk

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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接