假如有如下类,Customer和Order,在使用Hessian序列化Customer时,如果orders延迟加载,并且序列化时Hibernate的session已经关闭,则会抛出Hibernate的LazyInitializationException.
@Entity
public class Customer implements java.io.Serializable {
@Id
private long id;
private String name;
//一对多,延迟加载
@OneToMany(fetch=FetchType.LAZY)
@JoinColumn(name="CUSTOMER_ID")
private Set<Order> orders;
...........
@Entity
public class Order implements java.io.Serializable{
@Id
private long id;
.......
该Set为Hibernate的PersistentSet,是Hibernate的PersistentCollection的子类。原因是Hessian序列化时,会调用PersistentSet的方法导致Hibernate从session里加载数据,如果session已经关闭,就会抛出异常,导致序列化出错。不仅Set会出现,PersistentCollection的其他子类也会出现该现象,如PersistentList,PersistentBag,PersistentMap等。使用JDK的序列化不会出现该现象。
解决方案如下,可以为Hibernate的PersistentColletion定制一个Serializer,代码如下:
import com.caucho.hessian.io.AbstractHessianOutput;
import com.caucho.hessian.io.AbstractSerializer;
import com.caucho.hessian.io.CollectionSerializer;
import com.caucho.hessian.io.MapSerializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import org.hibernate.Hibernate;
import org.hibernate.collection.PersistentMap;
public class HibernateSerializer extends AbstractSerializer {
CollectionSerializer collectionSeiralizer = new CollectionSerializer();
MapSerializer mapSerializer = new MapSerializer();
@Override
public void writeObject(Object obj, AbstractHessianOutput out) throws IOException {
boolean init = Hibernate.isInitialized(obj);
if (init) {
out.writeObject(obj);
out.flush();
return;
}
if (PersistentMap.class.isAssignableFrom(obj.getClass())) {
//将没有初始化的Map序列化空的HashMap
mapSerializer.writeObject(new HashMap(), out);
} else {
//将没有初始化的List,Set等序列化为空的ArrayList
collectionSeiralizer.writeObject(new ArrayList(), out);
}
}
}
同时还需要定制一个序列化工厂SerializerFactory,代码如下:
import com.caucho.hessian.io.HessianProtocolException;
import com.caucho.hessian.io.Serializer;
import com.caucho.hessian.io.SerializerFactory;
import org.hibernate.collection.PersistentCollection;
public class HibernateSerializerFactory extends SerializerFactory {
@Override
public Serializer getSerializer(Class cl) throws HessianProtocolException {
//Hibernate的集合API使用为HibernateSerializer序列化
if (PersistentCollection.class.isAssignableFrom(cl)) {
return new HibernateSerializer();
}
return super.getSerializer(cl);
}
}
可以调用HessianServlet.getSerializerFactory().addFactory()添加HibernateSerializerFactory 来使用该HibernateSerializer序列化Hibernate的PersistentCollection.
或者写一个serializers文件放到classpath的META-INF/hessian/目录下,该文件的内容为
org.hibernate.collection.PersistentCollection=HibernateSerializer
分享到:
相关推荐
NULL 博文链接:https://qinghua0208.iteye.com/blog/493516
hessian序列化.pdf
介绍自己不会查吗?这里有一个点就是Hessian的序列化与反序列化与原生序列化与反序列化不同,就以使用的Resin链而言,其中的javax.naming.spi
NULL 博文链接:https://inter12.iteye.com/blog/1555678
主要通过对二者简单的实现方式的对比,介绍了Java序列化和hessian序列化的差异,具有一定参考价值,需要的朋友可以了解下。
NULL 博文链接:https://san-yun.iteye.com/blog/1688510
Hessian 2.0序列化协议规范
Hessian RPC-RMI技术 整合Structs Spring Hibernate Ibatis 包含Hessian配置说明、服务器Server Demo、客户端Client Demo.
Nacos JRaft Hessian 反序列化 RCE 分析.pdf
hessian轻量级 rpc实现
基于Springmvc+hibernate+Hessian开发需要的架包
java hessian-3.0.38.jar。修改了原生的jar包,解决了hessian 序列化BigDecimal的精度问题。注意,请在hessian服务端和客户端中分别替换此jar包哦!! 只替换服务端hessian jar包还是会有问题。
在Spring+iabtis框架中,增加hessian接口,要实现以下几点: 1.绕过系统本身的认证,拦截器直接将该实现方法的servlet直接调用,需要重写拦截器。 2.由于绕过了spring和Struts,请求没有经过封装的事物管理器实例化,...
hessian.jar,Hessian的序列化输出 ,
默认就是⾛ dubbo 协议,单⼀⻓连接,进⾏的是 NIO 异步通信,基于 hessian 作为序列化协议。使⽤的场景是:传输数据量⼩ (每次请求在 100kb 以内),但是并发量很⾼。 为了要⽀持⾼并发场景,⼀般是服务提供者就⼏...
远程调用方法就是HttpInvoker:他也是将参数和返回值通过Java的序列化机制进行编组和反编组,它具有RMI的支持所有可序列化对象的优点。试使用Http协议传输二进制流的,同时又具有Hessian、Burlap(传输xml文本)的...
SOFA-Hessian 基于原生Hessian v4.0.51进行改进,目前已经蚂蚁金服内部稳定运行多年。我们修复了一些bug,增强了一些功能,并且添加了一些特性。包括:增加泛化序列化。增加 ClassNameResolver 和 ClassNameFilter ...
a --args gadget入参,多个参数使用多次该命令传入,例-a -a Calc-p --protocol [dubbo|http] 通讯协议名称,默认缺省dubbo-s --serialization [hessian|java] 序列化类型,默认缺省hessian-t --target 目标,例:...
Hessian多个版本下载,包括Hessian3.1.6,Hessian3.2.1,Hessian4.0.7