Java 休眠:无法反序列化 - 无效的流标头

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23049498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 20:18:48  来源:igfitidea点击:

Hibernate: Could not deserialize - invalid stream header

javaspringhibernatejpa

提问by bcosynot

Any ideas as to how I could resolve this error? I am using Spring JPA with Hibernate. Necessary details below.

关于如何解决此错误的任何想法?我在 Hibernate 中使用 Spring JPA。必要的细节如下。

Entity class 1:

实体类 1:

@Entity
@Table(name = "ways")
@TypeDef(name = "hstore", typeClass = HstoreUserType.class)
@Cacheable
public class Way {

    /**
     * Primary key for the row in table.
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    /**
     * The ID to represent it across the system.
     * Used for preserving historical information. 
     */
    @Column(name = "way_id")
    private Long wayId;

    /**
     * The version of the way this Object represents. 
     */
    @Column(name = "version")
    private Integer version;


    /**
     * The {@link User} that edited this version. 
     */
    @OneToOne
    @PrimaryKeyJoinColumn(name = "user_id")
    private User user;

    /**
     * Timestamp when this version of the Way was edited.
     */
    @Column(name = "tstamp")
    @Temporal(TemporalType.TIMESTAMP)
    private Date timestamp;

    /**
     * The changeset that this version of the way belongs to. 
     */
    @Column(name = "changeset_id")
    private Long changesetId;

    /**
     * All the tags this Way contains. 
     */
    @Type(type = "hstore")
    @Column(name = "tags", columnDefinition = "hstore")
    private Object2ObjectOpenHashMap<String, String> tags = new Object2ObjectOpenHashMap<String, String>(); 

    @Column(name = "bbox")
    private Geometry bbox;

    @Column(name = "linestring")
    private Geometry linestring;

    @Column(name = "nodes")
    private Long[] nodes;

    // getters and setters
}

Entity class for User:

用户的实体类:

@Entity
@Table(name = "users")
@Cacheable
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "name", unique = true)
    private String name;

    // getters and setters

}

And the stacktrace :

和堆栈跟踪:

The stacktrace is quite huge. I am pasting the whole stacktrace below for reference and a quick TL;DR here:

堆栈跟踪非常庞大。我在下面粘贴整个堆栈跟踪以供参考和快速 TL;DR 在这里:

javax.persistence.PersistenceException: org.hibernate.type.SerializationException: could not deserialize
Caused by: org.hibernate.type.SerializationException: could not deserialize
Caused by: java.io.StreamCorruptedException: invalid stream header: 30313033

Full stacktrace follows:

完整的堆栈跟踪如下:

javax.persistence.PersistenceException: org.hibernate.type.SerializationException: could not deserialize
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1361)
        at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289)
        at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:261)
        at org.hibernate.ejb.criteria.CriteriaQueryCompiler.getResultList(CriteriaQueryCompiler.java:260)
        at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:250)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFac
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySuppo
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeReava:92)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at com.sun.proxy.$Proxy36.findAll(Unknown Source)
        at com.osmrecommend.persistence.service.WayPersistenceServiceImpl.getAllWays(WayPersistenceServiceImpl.java:32)
        at com.osmrecommend.dao.WayDAO.getAllWays(WayDAO.java:37)
        at com.osmrecommend.cbf.TFIDFModelBuilder.get(TFIDFModelBuilder.java:90)
        at com.osmrecommend.cbf.TFIDFModelBuilder.get(TFIDFModelBuilder.java:36)
        at org.grouplens.grapht.util.MemoizingProvider.get(MemoizingProvider.java:59)
        at org.grouplens.lenskit.inject.StaticInjector.instantiate(StaticInjector.java:130)
        at org.grouplens.lenskit.inject.StaticInjector.apply(StaticInjector.java:137)
        at org.grouplens.lenskit.inject.StaticInjector.apply(StaticInjector.java:47)
        at org.grouplens.lenskit.eval.traintest.ComponentCache$NodeInstantiator.call(ComponentCache.java:166)
        at com.google.common.cache.LocalCache$LocalManualCache.load(LocalCache.java:4792)
        at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3599)
        at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2379)
        at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2342)
        at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2257)
        at com.google.common.cache.LocalCache.get(LocalCache.java:4000)
        at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4789)
        at org.grouplens.lenskit.eval.traintest.ComponentCache$Instantiator.apply(ComponentCache.java:126)
        at org.grouplens.lenskit.eval.traintest.ComponentCache$Instantiator.apply(ComponentCache.java:104)
        at org.grouplens.lenskit.inject.RecommenderInstantiator.apply(RecommenderInstantiator.java:109)
        at org.grouplens.lenskit.inject.RecommenderInstantiator.apply(RecommenderInstantiator.java:99)
        at org.grouplens.lenskit.inject.RecommenderInstantiator.replaceShareableNodes(RecommenderInstantiator.java:188)
        at org.grouplens.lenskit.inject.RecommenderInstantiator.instantiate(RecommenderInstantiator.java:99)
        at org.grouplens.lenskit.eval.traintest.LenskitEvalJob.buildRecommender(LenskitEvalJob.java:74)
        at org.grouplens.lenskit.eval.traintest.TrainTestJob.runEvaluation(TrainTestJob.java:117)
        at org.grouplens.lenskit.eval.traintest.TrainTestJob.call(TrainTestJob.java:101)
        at org.grouplens.lenskit.eval.traintest.JobGraph$JobNode.call(JobGraph.java:116)
        at org.grouplens.lenskit.eval.traintest.JobGraph$JobNode.call(JobGraph.java:102)
        at org.grouplens.lenskit.util.parallel.SequentialTaskGraphExecutor.execute(SequentialTaskGraphExecutor.java:37)
        at org.grouplens.lenskit.eval.traintest.TrainTestEvalTask.runEvaluations(TrainTestEvalTask.java:468)
        at org.grouplens.lenskit.eval.traintest.TrainTestEvalTask.perform(TrainTestEvalTask.java:398)
        at org.grouplens.lenskit.eval.traintest.SimpleEvaluator.call(SimpleEvaluator.java:313)
        at com.osmrecommend.app.OSMRecommendEval.main(OSMRecommendEval.java:94)
Caused by: org.hibernate.type.SerializationException: could not deserialize
        at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:262)
        at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:306)
        at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:131)
        at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:117)
        at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:39)
        at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor.doExtract(VarbinaryTypeDescriptor.java:67)
        at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:65)
        at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:269)
        at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:265)
        at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:238)
        at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:357)
        at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2695)
        at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1552)
        at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1484)
        at org.hibernate.loader.Loader.getRow(Loader.java:1384)
        at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:640)
        at org.hibernate.loader.Loader.doQuery(Loader.java:856)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
        at org.hibernate.loader.Loader.doList(Loader.java:2463)
        at org.hibernate.loader.Loader.doList(Loader.java:2449)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2279)
        at org.hibernate.loader.Loader.list(Loader.java:2274)
        at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470)
        at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
        at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:196)
2014-04-13 17:35:49 INFO  persistence.service.WayPersistenceServiceImpl:37 - All ways fetched in 331s
        at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1115)
        at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
        at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:252)
        ... 51 more
Caused by: java.io.StreamCorruptedException: invalid stream header: 30313033
        at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
        at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
        at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:328)
        at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:318)
        at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:237)
        ... 78 more

UPDATE:

更新:

I updated the Ways entity class to the following, but error still occurs :

我将 Ways 实体类更新为以下内容,但仍然发生错误:

@Entity
@Table(name = "ways")
@Cacheable
public class Way implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -7941769011539363185L;

    /**
     * Primary key for the row in table.
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    /**
     * The ID to represent it across the system.
     * Used for preserving historical information. 
     */
    @Column(name = "way_id")
    private Long wayId;

    /**
     * The version of the way this Object represents. 
     */
    @Column(name = "version")
    private Integer version;


    /**
     * The {@link User} that edited this version. 
     */
    @OneToOne
    @PrimaryKeyJoinColumn(name = "user_id")
    private User user;

    /**
     * Timestamp when this version of the Way was edited.
     */
    @Column(name = "tstamp")
    @Temporal(TemporalType.TIMESTAMP)
    private Date timestamp;

    /**
     * The changeset that this version of the way belongs to. 
     */
    @Column(name = "changeset_id")
    private Long changesetId;

    /**
     * All the tags this Way contains. 
     */
    @Column(name = "tags")
    private String tags; 

    @Column(name = "bbox")
    private Geometry bbox;

    @Column(name = "linestring")
    private Geometry linestring;

    @Column(name = "nodes")
    @ElementCollection(targetClass=Long.class)
    private List<Long> nodes;

采纳答案by Alexey Malev

This issue is happening when something cannot be deserialized (thank you, Captain Obvious). In your entity mappings the following looks suspicious:

当某些内容无法反序列化时,就会发生此问题(谢谢,Obvious 上尉)。在您的实体映射中,以下内容看起来很可疑:

@Type(type = "hstore")
@Column(name = "tags", columnDefinition = "hstore")
private Object2ObjectOpenHashMap<String, String> tags = new Object2ObjectOpenHashMap<String, String>(); 

@Column(name = "bbox")
private Geometry bbox;

@Column(name = "linestring")
private Geometry linestring;

My suggestion is either to take a look over Geometryand Object2ObjectHashMapclasses - check whether they are serializable itself andall their fields either serializable too, or marked with transientkeyword. Also if you post these classes here, this may help aswell. HstoreUserTypeclass listing may also be helpful.

我的建议是要么看看在GeometryObject2ObjectHashMap班-他们检查是否序列化本身所有的领域要么过于序列化,或打上transient关键字。此外,如果您在此处发布这些课程,这也可能有所帮助。HstoreUserType类列表也可能有帮助。

回答by Surendra Poranki

Please make sure your entity objects are implementing the Serializable interface. Please select the option to make your objects Serializable in whatever tool you are using.

请确保您的实体对象正在实现 Serializable 接口。请选择使您的对象在您使用的任何工具中可序列化的选项。

Some thing like this

像这样的事情

public class Way implements Serializable {
    private static final long serialVersionUID = 1L;

回答by Felipe Cadena

The problem should be for the Geometry relation, it is mapped as a regular column so Hibernate try to map a simple Column to a Geometry object. I had a similar problem and the solution was to explicity define the relation, something like:

问题应该是 Geometry 关系,它被映射为一个常规列,所以 Hibernate 尝试将一个简单的 Column 映射到一个 Geometry 对象。我有一个类似的问题,解决方案是明确定义关系,例如:

@OneToOne
@JoinColumn(name = "bbox")
private Geometry bbox;

回答by molholm

For others with the same error (does not answer this exact question)

对于其他有相同错误的人(不回答这个确切的问题)

I experienced this error with hibernate 4.3 and 5.0.5 due to fields of type java.time.LocalDateTime, I have several entities using LocalDateTime, but only one of them caused the issue, I don't know why.

由于类型字段java.time.LocalDateTime,我在hibernate 4.3 和 5.0.5 中遇到了这个错误,我有几个实体使用 LocalDateTime,但只有其中一个导致了问题,我不知道为什么。

It was fixed by adding the following dependency:

通过添加以下依赖项来修复它:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-java8</artifactId>
    <version>${hibernate.version}</version>
</dependency>

回答by kaba713

Regarding the answerfrom @molholm, I would advise against using a deprecated dependency. The specific problem is that earlier versions of Hibernate did not convert java.time.*by them self, so you had to write a converter. The latest version (5.2.1.Final from 06/2016) seems to have an integrated converter. But I would still advise you to write your own and add it to your attribute. I.e.:

关于@molholm的回答,我建议不要使用已弃用的依赖项。具体问题是早期版本的 Hibernate 并没有java.time.*自行转换,因此您必须编写一个转换器。最新版本(06/2016 的 5.2.1.Final)似乎有一个集成转换器。但我仍然建议您自己编写并将其添加到您的属性中。IE:

@Convert(converter = LocalDateConverter.class)
private LocalDate timestamp;

And here is the converter:

这是转换器:

import java.sql.Date;
import java.time.LocalDate;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

@Converter
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {

    @Override
    public Date convertToDatabaseColumn(LocalDate entityValue) {
        if (entityValue == null) {
            return null;
        }
        return Date.valueOf(entityValue);
    }

    @Override
    public LocalDate convertToEntityAttribute(Date databaseValue) {
        if (databaseValue == null) {
            return null;
        }
        return databaseValue.toLocalDate();
    }
}

回答by Alexey Simonov

Regarding the kaba713 answerand converting java.time.*by Hibernate.

关于kaba713 的答案java.time.*通过 Hibernate 进行转换。

I use org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;and it works with Spring-Boot 1.5.4.

我使用org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;并且它适用于 Spring-Boot 1.5.4。

@Column(name = "order_date", nullable = false)
@Convert(converter = Jsr310JpaConverters.LocalDateTimeConverter.class)
private LocalDateTime orderDate;

And we don't need to write a custom converter.

而且我们不需要编写自定义转换器。

回答by user8495084

I faced this issue :

我遇到了这个问题:

HTTP Status 500 - Request processing failed; nested exception is org.hibernate.type.SerializationException: could not deserialize

Got solution also.

也得到了解决。

For me db side some rows manually enteredthe data after trying to retrieve the data raised exception deleted the manually entered rows after that tried to retrieve the data so this time no exception. Means if you insert the data serialized entities through hibernate in db store it. Db stores serialized objects format and retrieve db rows through serialized entities.

对我来说,数据库端的一些行在尝试检索数据后手动输入数据引发异常删除了手动输入的行之后尝试检索数据所以这次没有例外。 意味着如果您通过 hibernate 在 db 中插入数据序列化实体存储它。db 存储序列化对象格式并通过序列化实体检索 db 行。

回答by Anand Rockzz

I was facing this on a @NamedNativeQuery+ @SqlResultSetMappingscenario. The @ConstructorResult's targetClass had a Custom Enum inside. Changing it to String and later converting it in my code resolved the issue.

我在@NamedNativeQuery+@SqlResultSetMapping场景中遇到了这个问题。@ConstructorResult 的 targetClass 里面有一个 Custom Enum。将其更改为 String 并稍后在我的代码中将其转换解决了该问题。

回答by Benjamín Valero

The answer from Alexey Simonov almost works for me. However, I am still forced to used Java 7 and I am using the java.timebackport from ThreeTen.

Alexey Simonov 的回答几乎对我有用。不过,我仍然不得不使用的Java 7和我使用的java.time从反向移植ThreeTen

In my case, I have just used a different converter suited for the backported classes:

就我而言,我刚刚使用了一个适用于反向移植类的不同转换器:

@Column(name = "lastupdate", nullable = false)
@Convert(converter = ThreeTenBackPortJpaConverters.LocalDateConverter.class)
private LocalDate lastUpdate;

回答by Curtis Yallop

Your entity mapping annotations (or xml) do not match your db table. So hydration/deserialization failed.

您的实体映射注释(或 xml)与您的 db 表不匹配。所以水化/反序列化失败。

So which column is the problem? It does not tell you directly.

那么问题出在哪一列呢?它不会直接告诉你。

One clue is the hex codes at the end eg invalid stream header: 53....

一条线索是末尾的十六进制代码,例如无效流标头:53....

53 happens to be the ascii code for "S". (https://ascii.cl/)

53恰好是“S”的ASCII码。( https://ascii.cl/)

You can get the hex like this: select hex(MyColumn) from MyTable;

你可以得到这样的十六进制: select hex(MyColumn) from MyTable;

So you can look at the hex of suspicious columns until you find it.

因此,您可以查看可疑列的十六进制,直到找到为止。

Also, you can remove the columns one-by-one from the entity-mapping (eg comment out @Column and replace it with @Transient) until it works. Start with the suspicious ones eg enums or custom serializers. Or perhaps with any columns you just added that might have made it break.

此外,您可以从实体映射中一一删除列(例如注释掉@Column 并用@Transient 替换它),直到它工作为止。从可疑的开始,例如枚举或自定义序列化程序。或者也许您刚刚添加的任何列可能会使其中断。