我正在写一个小东西,用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传递到表现层。
请各位多指教。谢谢。