您的位置:首页 > 其它

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

2015-06-02 21:40 477 查看

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代理对象或者延迟加载的对象,则过滤掉,不序列化。如果有值,就序列化。
<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">package</span></span> com.test.json;

<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">import</span></span> org.hibernate.collection.spi.PersistentCollection;
<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">import</span></span> org.hibernate.proxy.HibernateProxy;
<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">import</span></span> org.hibernate.proxy.LazyInitializer;

<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">import</span></span> com.alibaba.fastjson.serializer.PropertyFilter;

<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">public</span></span> <span class="class" style="color: rgb(68, 85, 136); font-weight: bold;"><span style="background-color: rgb(248, 248, 255);"><span class="keyword" style="color: rgb(51, 51, 51);">class</span> <span class="title">SimplePropertyFilter</span> <span class="keyword" style="color: rgb(51, 51, 51);">implements</span> <span class="title">PropertyFilter</span> {</span></span>

<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="javadoc" style="color: rgb(153, 153, 136); font-style: italic;">/**
<span class="indent">  </span> * 过滤不需要被序列化的属性,主要是应用于Hibernate的代理和管理。
<span class="indent">  </span> * <span class="javadoctag">@param</span> object 属性所在的对象
<span class="indent">  </span> * <span class="javadoctag">@param</span> name 属性名
<span class="indent">  </span> * <span class="javadoctag">@param</span> value 属性值
<span class="indent">  </span> * <span class="javadoctag">@return</span> 返回false属性将被忽略,ture属性将被保留
<span class="indent">  </span> */</span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="annotation">@Override</span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="keyword" style="font-weight: bold;">public</span></span> <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">boolean</span></span> apply(Object object, String name, Object value) {
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">if</span></span> (value <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">instanceof</span></span> HibernateProxy) {<span class="comment" style="color: rgb(153, 153, 136); font-style: italic;"><span style="background-color: rgb(248, 248, 255);">//hibernate代理对象</span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span></span>LazyInitializer initializer = ((HibernateProxy) value).getHibernateLazyInitializer();
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">if</span></span> (initializer.isUninitialized()) {
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">return</span></span> <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">false</span></span>;
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span></span>}
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>} <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">else</span></span> <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">if</span></span> (value <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">instanceof</span></span> PersistentCollection) {<span class="comment" style="color: rgb(153, 153, 136); font-style: italic;"><span style="background-color: rgb(248, 248, 255);">//实体关联集合一对多等</span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span></span>PersistentCollection collection = (PersistentCollection) value;
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">if</span></span> (!collection.wasInitialized()) {
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">return</span></span> <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">false</span></span>;
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span></span>}
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span></span>Object val = collection.getValue();
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">if</span></span> (val == <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">null</span></span>) {
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">return</span></span> <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">false</span></span>;
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span></span>}
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>}
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">return</span></span> <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">true</span></span>;
<span class="indent"><span style="background-color: rgb(248, 248, 255);">  </span></span>}

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

调用的时候,使用如下的方式即可,声明一个SimplePropertyFilter
@RequestMapping(<span class="string" style="color: rgb(221, 17, 68);"><span style="background-color: rgb(248, 248, 255);">"/json"</span></span>)
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="keyword" style="font-weight: bold;">public</span></span> <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">void</span></span> test(HttpServletRequest request, HttpServletResponse response) {
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>Tags tags = tagsDaoImpl.<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">get</span></span>(<span class="number" style="color: rgb(0, 153, 153);"><span style="background-color: rgb(248, 248, 255);">2</span></span>);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>Tags parentTags = tagsDaoImpl.<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">get</span></span>(<span class="number" style="color: rgb(0, 153, 153);"><span style="background-color: rgb(248, 248, 255);">1</span></span>);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>tags.setParentTags(parentTags);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">long</span></span> d = System.nanoTime();
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>SimplePropertyFilter filter = <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">new</span></span> SimplePropertyFilter();
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>String json = JSON.toJSONString(tags, filter);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>System.<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">out</span></span>.println(System.nanoTime() -d);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>ObjectMapper mapper = <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">new</span></span> ObjectMapper();
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>mapper.registerModule(<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">new</span></span> Hibernate4Module());
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>mapper.setSerializationInclusion(Include.NON_NULL);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">long</span></span> d2 = System.nanoTime();
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>String json2 = <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">null</span></span>;
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">try</span></span> {
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span></span>json2 = mapper.writeValueAsString(tags);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>} <span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">catch</span></span> (JsonProcessingException e) {
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>}
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>System.<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">out</span></span>.println(System.nanoTime() - d2);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>System.<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">out</span></span>.println(json);
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>System.<span class="keyword" style="font-weight: bold;"><span style="background-color: rgb(248, 248, 255);">out</span></span>.println(json2);
<span class="indent"><span style="background-color: rgb(248, 248, 255);">  </span></span>}


上面的代码同样展示了,如果使用jackson,这里使用的是jackson2,想序列化hibernate代理和延迟加载的对象,你需要引入hibernate4module。Maven以来如下
<span class="tag" style="color: rgb(0, 0, 128);"><span style="background-color: rgb(248, 248, 255);"><<span class="title">dependency</span>></span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>  <span class="tag" style="color: rgb(0, 0, 128);"><span style="background-color: rgb(248, 248, 255);"><<span class="title">groupId</span>></span></span>com.fasterxml.jackson.datatype<span class="tag" style="color: rgb(0, 0, 128);"><span style="background-color: rgb(248, 248, 255);"></<span class="title">groupId</span>></span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>  <span class="tag" style="color: rgb(0, 0, 128);"><span style="background-color: rgb(248, 248, 255);"><<span class="title">artifactId</span>></span></span>jackson-datatype-hibernate4<span class="tag" style="color: rgb(0, 0, 128);"><span style="background-color: rgb(248, 248, 255);"></<span class="title">artifactId</span>></span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span></span>  <span class="tag" style="color: rgb(0, 0, 128);"><span style="background-color: rgb(248, 248, 255);"><<span class="title">version</span>></span></span>2.2.3<span class="tag" style="color: rgb(0, 0, 128);"><span style="background-color: rgb(248, 248, 255);"></<span class="title">version</span>></span></span>
<span style="background-color: rgb(248, 248, 255);"><span class="indent">  </span><span class="indent">  </span><span class="tag" style="color: rgb(0, 0, 128);"></<span class="title">dependency</span>></span></span>
绝对原创,保留一切权利。转载请注明出处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: