私のDAO実装は、Tomcat7を使用したサーバーの起動時に、シリアル化できない例外をスローしています。何がこれを引き起こすのか?私の他のDAOはこれを行っていません。
クラスは次のとおりです。
package com.project.dao;
import Java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.project.model.User;
public class UserDAOImpl implements UserDAO {
private HibernateTemplate hibernateTemplate;
public void setSessionFactory(SessionFactory sessionFactory) {
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}
@Override
public void saveUser(User user) {
hibernateTemplate.saveOrUpdate(user);
}
@Override
@SuppressWarnings("unchecked")
public List<User> listUser() {
return hibernateTemplate.find("from User");
}
@Override
@SuppressWarnings("unchecked")
public User getUserByID(long userID) {
List<User> users= hibernateTemplate.find("from User where id = '" + userID + "'");
return users.size() > 0 ? users.get(0) : null;
}
}
これが私の設定です:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<bean id="myDataSource"
class="org.Apache.Tomcat.dbcp.dbcp.BasicDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/context</value>
</property>
<property name="username">
<value>someUser</value>
</property>
<property name="password">
<value>somePassword</value>
</property>
<!-- Disable the second-level cache -->
<!-- Echo all executed SQL to stdout -->
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
<value>com.project.model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="myUserDAO" class="com.project.dao.UserDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
これが私のスタックです:
SEVERE: IOException while loading persisted sessions: Java.io.WriteAbortedException: writing aborted; Java.io.NotSerializableException: com.news.dao.UserDAOImpl
Java.io.WriteAbortedException: writing aborted; Java.io.NotSerializableException: com.project.dao.UserDAOImpl
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1332)
at Java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.Java:1946)
at Java.io.ObjectInputStream.readSerialData(ObjectInputStream.Java:1870)
at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1752)
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1328)
at Java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.Java:1946)
at Java.io.ObjectInputStream.readSerialData(ObjectInputStream.Java:1870)
at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1752)
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1328)
at Java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.Java:1946)
at Java.io.ObjectInputStream.readSerialData(ObjectInputStream.Java:1870)
at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1752)
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1328)
at Java.io.ObjectInputStream.readObject(ObjectInputStream.Java:350)
at org.Apache.catalina.session.StandardSession.readObject(StandardSession.Java:1600)
at org.Apache.catalina.session.StandardSession.readObjectData(StandardSession.Java:1073)
at org.Apache.catalina.session.StandardManager.doLoad(StandardManager.Java:284)
at org.Apache.catalina.session.StandardManager.load(StandardManager.Java:204)
at org.Apache.catalina.session.StandardManager.startInternal(StandardManager.Java:470)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.StandardContext.startInternal(StandardContext.Java:5241)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.ContainerBase.startInternal(ContainerBase.Java:1033)
at org.Apache.catalina.core.StandardHost.startInternal(StandardHost.Java:774)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.ContainerBase.startInternal(ContainerBase.Java:1033)
at org.Apache.catalina.core.StandardEngine.startInternal(StandardEngine.Java:291)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.StandardService.startInternal(StandardService.Java:443)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.StandardServer.startInternal(StandardServer.Java:727)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.startup.Catalina.start(Catalina.Java:620)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at org.Apache.catalina.startup.Bootstrap.start(Bootstrap.Java:303)
at org.Apache.catalina.startup.Bootstrap.main(Bootstrap.Java:431)
Caused by: Java.io.NotSerializableException: com.project.dao.UserDAOImpl
at Java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.Java:1164)
at Java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.Java:1518)
at Java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.Java:1483)
at Java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.Java:1400)
at Java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.Java:1158)
at Java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.Java:1518)
at Java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.Java:1483)
at Java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.Java:1400)
at Java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.Java:1158)
at Java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.Java:1518)
at Java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.Java:1483)
at Java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.Java:1400)
at Java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.Java:1158)
at Java.io.ObjectOutputStream.writeObject(ObjectOutputStream.Java:330)
at org.Apache.catalina.session.StandardSession.writeObject(StandardSession.Java:1676)
at org.Apache.catalina.session.StandardSession.writeObjectData(StandardSession.Java:1090)
at org.Apache.catalina.session.StandardManager.doUnload(StandardManager.Java:411)
at org.Apache.catalina.session.StandardManager.unload(StandardManager.Java:353)
at org.Apache.catalina.session.StandardManager.stopInternal(StandardManager.Java:497)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.StandardContext$4.run(StandardContext.Java:5464)
at Java.lang.Thread.run(Thread.Java:662)
at org.Apache.catalina.core.StandardContext.stopInternal(StandardContext.Java:5481)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.ContainerBase.stopInternal(ContainerBase.Java:1072)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.ContainerBase.stopInternal(ContainerBase.Java:1072)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.StandardService.stopInternal(StandardService.Java:502)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.StandardServer.stopInternal(StandardServer.Java:748)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.startup.Catalina.stop(Catalina.Java:693)
at org.Apache.catalina.startup.Catalina.start(Catalina.Java:654)
... 6 more
Jul 31, 2011 9:27:21 PM org.Apache.catalina.session.StandardManager startInternal
SEVERE: Exception loading sessions from persistent storage
Java.io.WriteAbortedException: writing aborted; Java.io.NotSerializableException: com.project.dao.UserDAOImpl
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1332)
at Java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.Java:1946)
at Java.io.ObjectInputStream.readSerialData(ObjectInputStream.Java:1870)
at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1752)
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1328)
at Java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.Java:1946)
at Java.io.ObjectInputStream.readSerialData(ObjectInputStream.Java:1870)
at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1752)
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1328)
at Java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.Java:1946)
at Java.io.ObjectInputStream.readSerialData(ObjectInputStream.Java:1870)
at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1752)
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1328)
at Java.io.ObjectInputStream.readObject(ObjectInputStream.Java:350)
at org.Apache.catalina.session.StandardSession.readObject(StandardSession.Java:1600)
at org.Apache.catalina.session.StandardSession.readObjectData(StandardSession.Java:1073)
at org.Apache.catalina.session.StandardManager.doLoad(StandardManager.Java:284)
at org.Apache.catalina.session.StandardManager.load(StandardManager.Java:204)
at org.Apache.catalina.session.StandardManager.startInternal(StandardManager.Java:470)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.StandardContext.startInternal(StandardContext.Java:5241)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.ContainerBase.startInternal(ContainerBase.Java:1033)
at org.Apache.catalina.core.StandardHost.startInternal(StandardHost.Java:774)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.ContainerBase.startInternal(ContainerBase.Java:1033)
at org.Apache.catalina.core.StandardEngine.startInternal(StandardEngine.Java:291)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.StandardService.startInternal(StandardService.Java:443)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.core.StandardServer.startInternal(StandardServer.Java:727)
at org.Apache.catalina.util.LifecycleBase.start(LifecycleBase.Java:145)
at org.Apache.catalina.startup.Catalina.start(Catalina.Java:620)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at org.Apache.catalina.startup.Bootstrap.start(Bootstrap.Java:303)
at org.Apache.catalina.startup.Bootstrap.main(Bootstrap.Java:431)
Caused by: Java.io.NotSerializableException: com.project.dao.UserDAOImpl
at Java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.Java:1164)
at Java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.Java:1518)
at Java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.Java:1483)
at Java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.Java:1400)
at Java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.Java:1158)
at Java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.Java:1518)
at Java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.Java:1483)
at Java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.Java:1400)
at Java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.Java:1158)
at Java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.Java:1518)
at Java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.Java:1483)
at Java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.Java:1400)
at Java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.Java:1158)
at Java.io.ObjectOutputStream.writeObject(ObjectOutputStream.Java:330)
at org.Apache.catalina.session.StandardSession.writeObject(StandardSession.Java:1676)
at org.Apache.catalina.session.StandardSession.writeObjectData(StandardSession.Java:1090)
at org.Apache.catalina.session.StandardManager.doUnload(StandardManager.Java:411)
at org.Apache.catalina.session.StandardManager.unload(StandardManager.Java:353)
at org.Apache.catalina.session.StandardManager.stopInternal(StandardManager.Java:497)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.StandardContext$4.run(StandardContext.Java:5464)
at Java.lang.Thread.run(Thread.Java:662)
at org.Apache.catalina.core.StandardContext.stopInternal(StandardContext.Java:5481)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.ContainerBase.stopInternal(ContainerBase.Java:1072)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.ContainerBase.stopInternal(ContainerBase.Java:1072)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.StandardService.stopInternal(StandardService.Java:502)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.core.StandardServer.stopInternal(StandardServer.Java:748)
at org.Apache.catalina.util.LifecycleBase.stop(LifecycleBase.Java:225)
at org.Apache.catalina.startup.Catalina.stop(Catalina.Java:693)
at org.Apache.catalina.startup.Catalina.start(Catalina.Java:654)
... 6 more
UserDaoImpl
は、シリアル化する場合は Java.io.Serializable インターフェイスを実装する必要があります(スタックトレースは、クラスのインスタンスをオブジェクトストリームに書き込もうとしていることを示します)。
シリアル化されるインスタンスは、そのインスタンスのオブジェクトグラフ内のすべてのオブジェクトとともに、すべてシリアル化可能でなければなりません。
Serializableのjavadocsから、
クラスの直列化可能性は、Java.io.Serializableインターフェースを実装するクラスによって有効になります...グラフをトラバースすると、Serializableインターフェースをサポートしないオブジェクトが検出される場合があります。この場合、NotSerializableExceptionがスローされ、シリアル化できないオブジェクトのクラスを識別します。
これらの規則には例外があることに注意してください。オブジェクトのシリアル化がいつ行われ、NotSerializableExceptionを回避するために何が必要かを完全に理解するには、 Java Object Serialization Specification を読むことをお勧めします。
コードのどこかで、セッションにUserDAOを保存している(または、UserDAOへの参照を持つオブジェクトを保存している)ために発生しています。 Tomcatは、シャットダウン時にすべてのアクティブセッションの完全なオブジェクトグラフをシリアル化しようとし、その後、起動時にそれらを復元しようとします。これの核心は、Tomcatが「通常」Javaオブジェクトのシリアル化を使用するため、すべてのオブジェクトがSerializable
である必要があるということです。
対処方法:
Serializable
インターフェイスを実装し、transient
自体がシリアル化可能であるとは思わないので、hibernateTemplateをHibernateTemplate
としてマークする必要があります。本当に動作させるには、デシリアライズ時にhibernateTemplateを再初期化するコードを追加する必要があります。<Manager pathname="" />
要素内で、<Context>
をcontext.xmlに追加します。これは再起動後もセッションを永続化する必要が本当にない限り、あなたにとって最善の行動方針です。ここでの他の回答は、シリアル化についてよく説明しています。これはGoogleでの最初の結果であるため、問題の解決に本当に役立つ情報を追加したかったのです。
例外メッセージ自体は、どのクラスのどのフィールドがこの問題を引き起こしたかを示していません。クラスをシリアル化できず、一時的なキーワードを追加する必要がある場合、Javaはフィールドをシリアル化しようとしないため、問題の原因となっているフィールドを把握するのが難しい場合があります。
パラメータ-Dsun.io.serialization.extendedDebugInfo=true
をJava/Tomcatの起動時に追加すると、例外がはるかに便利になります。例外メッセージの表示例を次に示します。
Java.io.NotSerializableException: za.co.abc.presentation.control.Three
- field (class "za.co.abc.presentation.control.Two", name: "three", type: "class za.co.abc.presentation.control.Three")
- object (class "za.co.abc.presentation.control.Two", za.co.abc.presentation.control.Two@fbbb20)
- field (class "za.co.abc.presentation.control.One", name: "two", type: "class za.co.abc.presentation.control.Two")
- object (class "za.co.abc.presentation.control.One", za.co.abc.presentation.control.One@17ee6c9)
- field (class "za.co.abc.presentation.control.Trail", name: "one", type: "class za.co.abc.presentation.control.One")
- root object (class "za.co.abc.presentation.control.Trail", {/click-tests/home.htm=home})
Transientキーワードを使用してフィールドをシリアル化しない場合は、おそらくクラスが読み取られるときにそれらのフィールドを設定する必要があります。そのためにはreadObject()メソッドを実装する必要があります。以下に例を示します。
private void readObject(Java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
// magically read all non-transient fields from input stream and populate their values
in.defaultReadObject();
someTransientField = new NotSerializableClass();
}