【问题标题】:could not initialize proxy - no Session无法初始化代理 - 没有会话
【发布时间】:2013-03-03 16:51:05
【问题描述】:

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

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

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

这是我的技术:

  • 春季:3.2.1发布
  • 休眠 4.1.7.Final
  • 杰克逊 2
  • 杰克逊核心 2.0.4
  • 杰克逊数据绑定:2.0.4
  • jackson-datatype-hibernate4: 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 会起作用。但是,我一定不能把事情连线,因为我仍然会遇到异常。

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

感谢...

【问题讨论】:

    标签: json spring hibernate jackson


    【解决方案1】:

    这在 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 正在使用,高于 sn-p 就可以了,因此 EntityManagerFactory bean 可用。否则,只需注入 Hibernate SessionFactory 并传递给构造函数。

    无需使用 OpenSessionInView 模式。

    【讨论】:

    • 太棒了。从休眠 4、jpa 2.0 开始工作,数据类型为 2.6.0。但是你应该使用 EntityManager.unwrap(HibernateEntityManager.class).getSession().getSessionFactory() 而不是 emf.unwrap,因为 emf.unwrap 仅从 jpa 2.1 开始可用(虽然没有检查)。
    【解决方案2】:

    这是因为你试图序列化的对象有延迟加载的组件,你可以在你的web配置中添加OpenSessionInViewFilter来解决这个问题。

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

    在你的 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-09
      • 2018-09-28
      • 2015-01-13
      • 2011-12-01
      相关资源
      最近更新 更多