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

原文  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代理对象或者延迟加载的对象,则过滤掉,不序列化。如果有值,就序列化。

[java]  view plain  copy
  1. package com.test.json;  
  2.   
  3. import org.hibernate.collection.spi.PersistentCollection;  
  4. import org.hibernate.proxy.HibernateProxy;  
  5. import org.hibernate.proxy.LazyInitializer;  
  6.   
  7. import com.alibaba.fastjson.serializer.PropertyFilter;  
  8.   
  9. public class SimplePropertyFilter implements PropertyFilter {  
  10.   
  11.     /** 
  12.      * 过滤不需要被序列化的属性,主要是应用于Hibernate的代理和管理。 
  13.      * @param object 属性所在的对象 
  14.      * @param name 属性名 
  15.      * @param value 属性值 
  16.      * @return 返回false属性将被忽略,ture属性将被保留 
  17.      */  
  18.     @Override  
  19.     public boolean apply(Object object, String name, Object value) {  
  20.         if (value instanceof HibernateProxy) {//hibernate代理对象  
  21.             LazyInitializer initializer = ((HibernateProxy) value).getHibernateLazyInitializer();  
  22.             if (initializer.isUninitialized()) {  
  23.                 return false;  
  24.             }  
  25.         } else if (value instanceof PersistentCollection) {//实体关联集合一对多等  
  26.             PersistentCollection collection = (PersistentCollection) value;  
  27.             if (!collection.wasInitialized()) {  
  28.                 return false;  
  29.             }  
  30.             Object val = collection.getValue();  
  31.             if (val == null) {  
  32.                 return false;  
  33.             }  
  34.         }  
  35.         return true;  
  36.     }  
  37.   
  38. }  
当然,可以上述类,继续进行扩展,添加构造函数,配置,指定Class,以及该Class的哪个属性需要过滤。进行更精细化的控制。后面再续。

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

[java]  view plain  copy
  1. @RequestMapping("/json")  
  2.     public void test(HttpServletRequest request, HttpServletResponse response) {  
  3.         Tags tags = tagsDaoImpl.get(2);  
  4.         Tags parentTags = tagsDaoImpl.get(1);  
  5.         tags.setParentTags(parentTags);  
  6.           
  7.         long d = System.nanoTime();  
  8.         SimplePropertyFilter filter = new SimplePropertyFilter();  
  9.         String json = JSON.toJSONString(tags, filter);  
  10.         System.out.println(System.nanoTime() -d);  
  11.           
  12.         ObjectMapper mapper = new ObjectMapper();  
  13.         mapper.registerModule(new Hibernate4Module());  
  14.         mapper.setSerializationInclusion(Include.NON_NULL);  
  15.           
  16.         long d2 = System.nanoTime();  
  17.         String json2 = null;  
  18.         try {  
  19.             json2 = mapper.writeValueAsString(tags);  
  20.         } catch (JsonProcessingException e) {  
  21.               
  22.         }  
  23.         System.out.println(System.nanoTime() - d2);  
  24.         System.out.println(json);  
  25.         System.out.println(json2);  
  26.     }  

上面的代码同样展示了,如果使用jackson,这里使用的是jackson2,想序列化hibernate代理和延迟加载的对象,你需要引入hibernate4module。Maven以来如下

[html]  view plain  copy
  1. <dependency>  
  2.           <groupId>com.fasterxml.jackson.datatype</groupId>  
  3.           <artifactId>jackson-datatype-hibernate4</artifactId>  
  4.           <version>2.2.3</version>  
  5.         </dependency>  

PS: 还有个问题没解决,如果是hibernate代理对象或者延迟加载的对象(其实延迟加载对象就是代理对象),这里只实现了代理对象如果未初始化,则转json时忽略,期望的结果是能吧转的时候能吧id属性转过去,其他属性则忽略。

HibernateProxy 这个还没测试,不知道Hibernate4.3版本还可以使用这个类判断是否是代理对象了。调试时看到的是JavassistLazyInitializer这个类。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值