我正在寫一個小東西,用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傳遞到表現層。
請各位多指教。謝謝。
?