我正在写一个小东西,用hibernate做数据层,用hessian提供的remoting做业务层,表现层通过http的方式取得业务层的服务,有的地方需要把PO传递到表现层(有人不同意把PO和VO重用,但是我的观点是:大部分实体对象只要vo、po重用就可以了,只有vo、po差距较大的地方才分开,这样就做到了简洁性和可扩展性的良好折中)。
但是在我将一个PO传递到表现层的时候出现了下面的问题:
java.lang.InstantiationException: org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at com.caucho.hessian.io.JavaDeserializer.instantiate(JavaDeserializer.java:104)
at com.caucho.hessian.io.JavaDeserializer.readMap(JavaDeserializer.java:54)
at com.caucho.hessian.io.SerializerFactory.readMap(SerializerFactory.java:147)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:781)
at com.caucho.hessian.io.MapDeserializer.readMap(MapDeserializer.java:88)
at com.caucho.hessian.io.SerializerFactory.readMap(SerializerFactory.java:149)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:781)
at com.caucho.hessian.io.JavaDeserializer.readMap(JavaDeserializer.java:69)
at com.caucho.hessian.io.JavaDeserializer.readMap(JavaDeserializer.java:55)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:658)
at com.caucho.hessian.io.HessianInput.readReply(HessianInput.java:241)
at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:179)
at $Proxy2.loadByPK(Unknown Source)
at com.cownew.PIS.demo.client.HelloTest.testDAO(HelloTest.java:85)
at com.cownew.PIS.demo.client.HelloTest.main(HelloTest.java:94)
java.lang.reflect.UndeclaredThrowableException
at $Proxy2.loadByPK(Unknown Source)
at com.cownew.PIS.demo.client.HelloTest.testDAO(HelloTest.java:85)
at com.cownew.PIS.demo.client.HelloTest.main(HelloTest.java:94)
Caused by: java.io.IOException: java.lang.InstantiationException: org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer
at com.caucho.hessian.io.JavaDeserializer.readMap(JavaDeserializer.java:60)
at com.caucho.hessian.io.SerializerFactory.readMap(SerializerFactory.java:147)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:781)
at com.caucho.hessian.io.MapDeserializer.readMap(MapDeserializer.java:88)
at com.caucho.hessian.io.SerializerFactory.readMap(SerializerFactory.java:149)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:781)
at com.caucho.hessian.io.JavaDeserializer.readMap(JavaDeserializer.java:69)
at com.caucho.hessian.io.JavaDeserializer.readMap(JavaDeserializer.java:55)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:658)
at com.caucho.hessian.io.HessianInput.readReply(HessianInput.java:241)
at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:179)
... 3 more
我的这个对象是如下定义的:
package com.cownew.PIS.demo.common;
import com.cownew.PIS.framework.common.BaseObjectValue;
public class MaterialInfo extends BaseObjectValue
{
private String Id;
private String Number;
private PersonInfo Manager;
public void setId(String value)
{
this.Id=value;
}
public void setNumber(String value)
{
this.Number=value;
}
public void setManager(PersonInfo value)
{
this.Manager=value;
}
public String getId()
{
return Id;
}
public String getNumber()
{
return Number;
}
public PersonInfo getManager()
{
return Manager;
}
}
经跟踪发现原来是在反序列化getManager的返回值的时候出错的。hibernate使用CGLIB实现的惰性加载,这样getManager的返回值的类型其实是PersonInfo 的一个子类,其中有一个CGLIBLazyInitializer类型的字段,这个CGLIBLazyInitializer是没有默认构造函数的,这样就造成了反序列化失败。
我的解决方式是写一个DTOAssembler来将PO手动转换成VO,这个VO的类型和PO一样,但是对于关联属性进行了针对CGLIB的特别处理。然后把转换后的VO传递到表现层。
请各位多指教。谢谢。