Serializable对象的InvalidClassException

时间:2014-06-06 08:30:13

标签: java serialization glassfish entity eclipselink

我在与同事的代码集成时遇到了一些问题。

他有一个实体类,我们称之为FooEntity

@Entity
@XmlRootElement
@Table(name = "...")
public class FooEntity implements Serializable {

    private static final long serialVersionUID = ...;
    ...

    @Lob
    @Column(name = "OBJBYTES")
    private Serializable objBytes;

    ...
}

他正在创建他的DTO对象

public class FooDTO implements Serializable {

    private static final long serialVersionUID = ...;

    ...

    private Serializable obj;
    ...
}

通过助手类

public class FooHelper {

    ...

    public static Serializable createSBar() {
        Bar bar = generateBar();
        Serializable sBar = bar;
        return sBar;
    }

    ...

}

创建一个实现Bar接口的Serializable对象:

public class Bar implements Serializable {

    private static final long serialVersionUID = ...;

    private String myString;
    private byte[] myBytes;
}

在他的DAO中,他从他的DTO对象创建实体对象并将其保存到数据库并检索实体对象并将其映射到DTO对象。

在通过Query#getResultList检索符合特定条件的条目列表时,会抛出InvalidClassException此消息:

Local Exception Stack: 
Exception [EclipseLink-66] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Could not deserialize object from byte array.
Internal Exception: java.io.InvalidClassException: com.my.package.Bar; local class incompatible: stream classdesc serialVersionUID = 4849912519109332230, local class serialVersionUID = -1015090985675288072
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[objBytes-->FOO_TABLE.OBJBYTES]
Descriptor: RelationalDescriptor(com.my.package.entity.FooEntity --> [DatabaseTable(FOO_TABLE)])
    at org.eclipse.persistence.exceptions.DescriptorException.notDeserializable(DescriptorException.java:1218)
    at org.eclipse.persistence.mappings.converters.SerializedObjectConverter.convertDataValueToObjectValue(SerializedObjectConverter.java:72)
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getAttributeValue(AbstractDirectMapping.java:699)
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.valueFromRow(AbstractDirectMapping.java:1299)
    at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.buildCloneFromRow(AbstractDirectMapping.java:1258)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:1548)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:1694)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:664)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:601)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:560)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:717)
    at org.eclipse.persistence.queries.ReadObjectQuery.registerResultInUnitOfWork(ReadObjectQuery.java:778)
    at org.eclipse.persistence.queries.ReadObjectQuery.executeObjectLevelReadQuery(ReadObjectQuery.java:457)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1081)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
    at org.eclipse.persistence.queries.ReadObjectQuery.execute(ReadObjectQuery.java:418)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1128)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
    at org.eclipse.persistence.internal.indirection.NoIndirectionPolicy.valueFromQuery(NoIndirectionPolicy.java:323)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRowInternal(ForeignReferenceMapping.java:2098)
    at org.eclipse.persistence.mappings.OneToOneMapping.valueFromRowInternal(OneToOneMapping.java:1695)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRow(ForeignReferenceMapping.java:1987)
    at org.eclipse.persistence.mappings.ForeignReferenceMapping.buildCloneFromRow(ForeignReferenceMapping.java:276)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:1548)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:1694)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:664)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:601)
    at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:560)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:717)
    at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:769)
    at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:433)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1081)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:392)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1128)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1463)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:485)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:742)
    at com.my.package.dao.FooDAO.getRange(FooDAO.java:584)
    ...
Caused by: java.io.InvalidClassException: com.my.package.Bar; local class incompatible: stream classdesc serialVersionUID = 4849912519109332230, local class serialVersionUID = -1015090985675288072
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:560)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1599)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1494)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1748)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1327)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:349)
    at org.eclipse.persistence.mappings.converters.SerializedObjectConverter.convertDataValueToObjectValue(SerializedObjectConverter.java:70)
    ... 165 more

可能还需要注意的是,在Glassfish 3.1.2.2中部署应用程序时,日志中会显示以下消息:

[#|2014-06-05T12:39:01.301+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.FooEntity actually got transformed|#]

[#|2014-06-05T12:39:01.310+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo2Entity actually got transformed|#]

[#|2014-06-05T12:39:01.316+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo3Entity actually got transformed|#]

[#|2014-06-05T12:39:01.322+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo4Entity actually got transformed|#]

[#|2014-06-05T12:39:01.327+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo5Entity actually got transformed|#]

[#|2014-06-05T12:39:01.332+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo6Entity actually got transformed|#]

[#|2014-06-05T12:39:01.337+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo7Entity actually got transformed|#]

[#|2014-06-05T12:39:01.345+0200|INFO|glassfish3.1.2|javax.enterprise.system.core.classloading.com.sun.enterprise.loader|_ThreadID=28;_ThreadName=Thread-2;|com.my.package.entity.Foo8Entity actually got transformed|#]

有人可以解释为什么会发生这种异常以及如何解决这个问题吗? 另外,我认为将实体对象用作JAXB对象并不是一个好习惯,对吧?

1 个答案:

答案 0 :(得分:1)

如错误消息所示:

  

内部异常:java.io.InvalidClassException:com.my.package.Bar;   本地类不兼容:stream classdesc serialVersionUID =   4849912519109332230,本地类serialVersionUID =   -1015090985675288072

似乎有两个不同的serialVersionUIDs,这似乎导致错误。你必须找出为什么有不同的值,可能在此期间改变了价值。