使用 Gilead 持久化具有继承的类
Posted
技术标签:
【中文标题】使用 Gilead 持久化具有继承的类【英文标题】:Persist classes with inheritance using Gilead 【发布时间】:2009-08-21 20:54:37 【问题描述】:我正在使用 Gilead 将我的实体持久保存在我的 GWT 项目中,但我遇到了一个问题。我想创建一个父类来保存一些在我的实体中通用的属性(id 等)。持久化时出现空指针异常。
父类:
public abstract class Entity extends LightEntity implements Serializable
protected Long id;
public Entity()
儿童班:
public class Person extends Entity
private String firstName;
private String lastName;
public Person()
休眠映射文件:
<hibernate-mapping>
<class name="com.domain.Entity" abstract="true" >
<id name="id" type="long">
<column name="ID"/>
<generator class="native" />
</id>
<union-subclass name="com.domain.Person" table="PERSON">
<property name="id" type="long" />
<property name="firstName" type="string">
<column name="FIRST_NAME" length="45" not-null="true" />
</property>
<property name="lastName" type="string">
<column name="LAST_NAME" length="45" not-null="true" />
</property>
</union-subclass>
</class>
</hibernate-mapping>
持久化时的堆栈跟踪:
java.lang.NullPointerException 在 net.sf.gilead.gwt.PersistentRemoteService.processCall(PersistentRemoteService.java:170) 在 com.google.gwt.user.server.rpc.RemoteServiceServlet.doPost(RemoteServiceServlet.java:86) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:754) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:847) 在 org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:315) 在 org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218) 在 org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) 在 org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) 在 com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94) 在 com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222) 在 org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) 在 org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) 在 org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587) 在 org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166) 在 org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) 在 org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) 在 org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587) 在 org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096) 在 org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:288) 在 com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:647) 在 com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:579) 在 com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:831) 在 com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341) 在 com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263) 在 com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214) 在 com.sun.enterprise.web.portunif.PortUnificationPipeline$PUTask.doTask(PortUnificationPipeline.java:380) 在 com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265) 在 com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
【问题讨论】:
【参考方案1】:您使用的是吉利德 1.2.2 吗?
如果是,升级吉利德。然后再次运行并检查新的异常消息。很可能只是某种错误配置。
完整解释:
如果查看1.2.1版本的PersistentRemoteService.java的源代码
PersistentRemoteService.java v1.2.1
在第 170 行,您会看到以下行
return RPCCopy.getInstance().encodeResponseForFailure(null, ex, rpcRequest.getSerializationPolicy());
如果rpcRequest
为空,这显然会失败并显示NullPointerException
。
在第 143 行时会发生这种情况
// Decode request
rpcRequest = RPCCopy.getInstance().decodeRequest(payload, this.getClass(), this);
decodeRequest
-方法抛出一个IncompatibleRemoteServiceException
。在你的情况下它会做什么。
从版本 1.2.2 开始,第 170 行更改为
if (rpcRequest != null)
return RPCCopy.getInstance().encodeResponseForFailure(null, ex, rpcRequest.getSerializationPolicy());
else
return RPCCopy.getInstance().encodeResponseForFailure(null, ex);
现在您应该得到正确的异常 (IncompatibleRemoteServiceException
),它指出了真正的问题。
你也可以在SVN中查看对应的commit/fix
Bad exception fix (issue 2663344)
以及Bug-Tracker for Gilead中对应的问题条目
Wrong exception
所以这个问题自 2009 年 2 月 7 日或 Gilead 版本 1.2.2(2009 年 3 月 13 日)起在 SVN 中得到解决
【讨论】:
【参考方案2】:不确定是否有帮助。只是一种猜测。您是否尝试过非抽象超类?有时在序列化之前手动取消/急切加载惰性对象引用或列表(当然在当前事务范围之外)是可行的,并且不需要 Gilead。
【讨论】:
以上是关于使用 Gilead 持久化具有继承的类的主要内容,如果未能解决你的问题,请参考以下文章