【问题标题】:InvalidClassException on Serializable objects可序列化对象上的 InvalidClassException
【发布时间】:2014-06-06 08:30:12
【问题描述】:

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

他有一个实体类,我们称之为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;
    }

    ...

}

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

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 对象不是一个好习惯,对吧?

【问题讨论】:

  • 您或您的同事之间是否更改了serialVersionUID
  • 天啊,他在数据库中记录了具有不同 UID 的实体...请发布答案,以便我接受。 :)

标签: java serialization glassfish entity eclipselink


【解决方案1】:

如错误信息所示:

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

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

【讨论】:

    猜你喜欢
    • 2013-01-21
    • 2012-12-25
    • 2015-03-20
    • 2022-11-11
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多