Сохранение классов с наследованием с использованием Gilead
Вопрос
Я использую 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.Опубликовать (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.Стандартный трубопровод.doInvoke(стандартный трубопровод.java:648) в org.apache.catalina.core.Стандартный трубопровод.doInvoke(стандартный трубопровод.java:593) на com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94) на com.sun.enterprise.web.PESessionLockingStandardPipeline.вызвать (PESessionLockingStandardPipeline.java:98) в org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222) в org.apache.catalina.core.Стандартный трубопровод.doInvoke(стандартный трубопровод.java:648) в org.apache.catalina.core.Стандартный трубопровод.doInvoke(стандартный трубопровод.java:593) в org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587) в org.apache.catalina.core.Контейнерная база.вызов (ContainerBase.java:1096) в org.apache.catalina.core.StandardEngineValve.вызов (StandardEngineValve.java:166) в org.apache.catalina.core.Стандартный трубопровод.doInvoke(стандартный трубопровод.java:648) в org.apache.catalina.core.Стандартный трубопровод.Выполните вызов (StandardPipeline.java:593) в org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587) в org.apache.catalina.core.База контейнеров.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.База задач.run (TaskBase.java:265) в com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Решение
Вы используете Gilead < 1.2.2?
Если да, обновите Gilead.А затем запустите еще раз и проверьте новое сообщение об исключении.Скорее всего, просто какая-то неправильная конфигурация.
Полное объяснение:
Если вы проверите исходный код PersistentRemoteService.java в версии 1.2.1
PersistentRemoteService.java версия 1.2.1
в строке 170 вы видите следующую строку
return RPCCopy.getInstance().encodeResponseForFailure(null, ex, rpcRequest.getSerializationPolicy());
Это, очевидно, терпит неудачу с NullPointerException
если rpcRequest
равно нулю.
Это происходит, когда в строке 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
Исправление плохого исключения (проблема 2663344)
и соответствующая запись о проблеме в Баг-трекер для Gilead
Таким образом, эта проблема решена в SVN с 07 февраля 2009 года или с версии Gilead 1.2.2 (13 марта 2009 года)
Другие советы
Не уверен, поможет ли это.Просто предположение.Вы пробовали использовать неабстрактный суперкласс?Иногда ручное аннулирование / быстрая загрузка ссылок на отложенные объекты или списков перед сериализацией (и, конечно, за пределами текущей области транзакции) просто работает, и нет необходимости в Gilead.