美好的一天, 我花了相当多的时间Googlin'并从JSON 1升级到JSON 2但是当我尝试返回一个实体列表时,我得到了例外:
“收到异常无法写入JSON:无法初始化代理 - 无会话(通过参考链:”
我知道这与Hibernate lazy init有关,但我还没弄清楚如何修复它。我认为jackson-module-hibernate项目是解决方案。但是我无法使它发挥作用。
这是我的技术:
我正在使用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将起作用。但是,由于我仍然有例外,所以我不能把事情连接起来。
有人可以在这看到任何错误吗?
...感激
答案 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>