fastjson序列化hibernate代理和延迟加载对象出现no session异常的解决办法

fastjson序列化hibernate代理和延迟加载对象出现org.hibernate.LazyInitializationException: Failed to lazily initialize a collection of role: com.eecn.warehouse.api.model.Tags.childTags,Could not initialize proxy - no Session。

对于这个可以使用fastjson给出的扩展点,实现PropertyFilter接口,过滤不想序列化的属性

下面的实现,如果是hibernate代理对象或者延迟加载的对象,则过滤掉,不序列化。如果有值,就序列化。

package com.test.json;

import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;

import com.alibaba.fastjson.serializer.PropertyFilter;

public class SimplePropertyFilter implements PropertyFilter {

  /**
  * 过滤不需要被序列化的属性,主要是应用于Hibernate的代理和管理。
  * @param object 属性所在的对象
  * @param name 属性  * @param value 属性  * @return 返回false属性将被忽略,ture属性将被保留
  */
  @Override
  public boolean apply(Object object,String name,Object value) {
    if (value instanceof HibernateProxy) {//hibernate代理对象
      LazyInitializer initializer = ((HibernateProxy) value).getHibernateLazyInitializer();
      if (initializer.isUninitialized()) {
        return false;
      }
    } else if (value instanceof PersistentCollection) {//实体关联集合一对多等
      PersistentCollection collection = (PersistentCollection) value;
      if (!collection.wasInitialized()) {
        return false;
      }
      Object val = collection.getValue();
      if (val == null) {
        return false;
      }
    }
    return true;
  }

}
当然,可以上述类,继续进行扩展,添加构造函数,配置,指定Class,以及该Class的哪个属性需要过滤。进行更精细化的控制。后面再续。

调用的时候,使用如下的方式即可,声明一个SimplePropertyFilter

@RequestMapping("/json")
  public void test(HttpServletRequest request,HttpServletResponse response) {
    Tags tags = tagsDaoImpl.get(2);
    Tags parentTags = tagsDaoImpl.get(1);
    tags.setParentTags(parentTags);
    
    long d = System.nanoTime();
    SimplePropertyFilter filter = new SimplePropertyFilter();
    String json = JSON.toJSONString(tags,filter);
    System.out.println(System.nanoTime() -d);
    
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new Hibernate4Module());
    mapper.setSerializationInclusion(Include.NON_NULL);
    
    long d2 = System.nanoTime();
    String json2 = null;
    try {
      json2 = mapper.writeValueAsstring(tags);
    } catch (JsonProcessingException e) {
      
    }
    System.out.println(System.nanoTime() - d2);
    System.out.println(json);
    System.out.println(json2);
  }

上面的代码同样展示了,如果使用jackson,这里使用的是jackson2,想序列化hibernate代理和延迟加载的对象,你需要引入hibernate4module。Maven以来如下
<dependency>
      <groupId>com.fasterxml.jackson.datatype</groupId>
      <artifactId>jackson-datatype-hibernate4</artifactId>
      <version>2.2.3</version>
    </dependency>
绝对原创,保留一切权利。转载请注明出处。

相关文章

AJAX是一种基于JavaScript和XML的技术,能够使网页实现异步交...
在网页开发中,我们常常需要通过Ajax从后端获取数据并在页面...
在前端开发中,经常需要循环JSON对象数组进行数据操作。使用...
AJAX(Asynchronous JavaScript and XML)是一种用于创建 We...
AJAX技术被广泛应用于现代Web开发,它可以在无需重新加载页面...
Ajax是一种通过JavaScript和HTTP请求交互的技术,可以实现无...