原文 http://blog.csdn.net/skmbw/article/details/12650827
astjson序列化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 { @Override public boolean apply(Object object, String name, Object value) { if (value instanceof HibernateProxy) { 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 >
PS: 还有个问题没解决,如果是hibernate代理对象或者延迟加载的对象(其实延迟加载对象就是代理对象),这里只实现了代理对象如果未初始化,则转json时忽略,期望的结果是能吧转的时候能吧id属性转过去,其他属性则忽略。
HibernateProxy 这个还没测试,不知道Hibernate4.3版本还可以使用这个类判断是否是代理对象了。调试时看到的是JavassistLazyInitializer这个类。