【问题标题】:Hibernate throws StreamCorruptedException: invalid stream headerHibernate 抛出 StreamCorruptedException:无效的流标头
【发布时间】:2012-08-06 09:51:56
【问题描述】:

我有这样的课,

class SampleClass implements Serializable {
    String name;
    Serializable fieldName;
}

还有另一个类,

class AnotherClass implements Serializable {
    SampleClass sampleClass;
}

两个类都有自己的 getter 和 setter 方法。

在主类中,我从 getter 函数中获取了 sampleClass 变量,并尝试使用 sampleClass 对象。但是当我使用它时,我遇到了could not deserialize之类的错误。

如何访问SampleClass 的成员,或者我们应该有Serializable 类型的字段成员?

谢谢。


编辑: 我正在使用休眠,它使用 aemploye 和 aaddress 表之间的多对一关系。

我为上述两个表创建了 Hibernate 配置文件和 Net beans 中的逆向工程文件。

然后我生成了 POJO 类。

类和xml是:

Aaddress.hbm.xml

<hibernate-mapping>
<class name="hibernatetutor.tablebeans.Aaddress" table="aaddress" schema="public">
    <id name="sno" type="int">
        <column name="sno" />
        <generator class="assigned" />
    </id>
    <property name="street" type="serializable">
        <column name="street" />
    </property>
    <set name="aemployes" inverse="true">
        <key>
            <column name="address" />
        </key>
        <one-to-many class="hibernatetutor.tablebeans.Aemploye" />
    </set>
</class>

Aemploye.hbm.xml

<hibernate-mapping>
<class name="hibernatetutor.tablebeans.Aemploye" table="aemploye" schema="public">
    <id name="id" type="int">
        <column name="id" />
        <generator class="assigned" />
    </id>
    <many-to-one name="aaddress" class="hibernatetutor.tablebeans.Aaddress" fetch="select">
        <column name="address" />
    </many-to-one>
    <property name="name" type="string">
        <column name="name" />
    </property>
</class>

Aaddress.java

public class Aaddress implements java.io.Serializable {

    private int sno;
    private Serializable street;
    private Set aemployes = new HashSet(0);

    public int getSno() {
        return this.sno;
    }

    public void setSno(int sno) {
        this.sno = sno;
    }

    public Serializable getStreet() {
        return this.street;
    }

    public void setStreet(Serializable street) {
        this.street = street;
    }

    public Set getAemployes() {
        return this.aemployes;
    }

    public void setAemployes(Set aemployes) {
        this.aemployes = aemployes;
    }
}

Aemploye.java

public class Aemploye implements java.io.Serializable {

    private int id;
    private Aaddress aaddress;
    private String name;

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Aaddress getAaddress() {
        return this.aaddress;
    }

    public void setAaddress(Aaddress aaddress) {
        this.aaddress = aaddress;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Main.java

private void getData() {
    Session session = HibernateUtils.getInstance().openSession();
    Query query = session.createQuery("from Aemploye where id=:id");
    query.setParameter("id", 1);
    Aemploye a = (Aemploye) query.uniqueResult();
    Aaddress a1 = a.getAaddress();
    System.out.println(a1.getStreet());
}

错误是:

org.hibernate.type.SerializationException: could not deserialize
    at org.hibernate.util.SerializationHelper.deserialize(SerializationHelper.java:217)
    at org.hibernate.util.SerializationHelper.deserialize(SerializationHelper.java:240)
    at org.hibernate.type.SerializableType.fromBytes(SerializableType.java:82)
    at org.hibernate.type.SerializableType.get(SerializableType.java:39)
    at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:163)
    at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:154)
    at org.hibernate.type.AbstractType.hydrate(AbstractType.java:81)
    at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2096)
    at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1380)
    at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1308)
    at org.hibernate.loader.Loader.getRow(Loader.java:1206)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:580)
    at org.hibernate.loader.Loader.doQuery(Loader.java:701)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
    at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3044)
    at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:395)
    at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
    at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
    at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:98)
    at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
    at org.hibernate.impl.SessionImpl.immediateLoad(SessionImpl.java:836)
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:66)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
    at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
    at hibernatetutor.tablebeans.Aaddress$$EnhancerByCGLIB$$44bec229.getStreet(<generated>)
    at hibernatetutor.Main.getData(Main.java:33)
    at hibernatetutor.Main.main(Main.java:24)
Caused by: java.io.StreamCorruptedException: invalid stream header
    at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:753)
    at java.io.ObjectInputStream.<init>(ObjectInputStream.java:268)
    at org.hibernate.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:252)
    at org.hibernate.util.SerializationHelper.deserialize(SerializationHelper.java:209)
    ... 29 more

【问题讨论】:

  • 为其添加适当的 getter 和 setter
  • 你能贴一些代码吗?否则很难提供帮助。
  • 这本身不是序列化问题,更多的是与 Hibernate 框架有关。您应该考虑重新标记并重新表述问题。
  • 为什么要将街道字段的类型设置为可序列化?
  • @Boopathy 为什么不为street 使用String 属性而不是Serializable?此外,该问题很可能是由类型为TEXT 的数据库列引起的,这不适用于二进制数据。如果要存储二进制文件(例如序列化对象),建议将其类型更改为BYTEA

标签: java hibernate serialization deserialization


【解决方案1】:

根据问题和评论部分的一些信息,我认为您的问题是由以下原因引起的:

您出于某种原因选择了 street 属性为可序列化类型。在您的表中,该列已定义为TEXT 类型。 Hibernate 可能设法将序列化数据保存到列中,但数据库可能无法使它们保持不变。因此,在检索时,现在出现乱码的序列化无法反序列化。

解决方案是,正如 Petr Pudlák 所指出的,让您的映射正确。如果您选择合适的二进制类型,例如BYTEA,那么您将能够原封不动地存储二进制数据。然后检索应该工作。

恕我直言,这不是正确的解决方案,首先是在您的 java 代码中选择合适的数据类型。将街道类型设为 Serializable 会让任何查看您的代码的人感到困惑。 String 可能更有意义,并且也非常适合列类型 TEXT

【讨论】:

    【解决方案2】:

    我试过你的课程,它对我有用:

    import java.io.*;
    
    class SampleClass implements Serializable {
          String name;
          Serializable fieldName;
    }
    
    class AnotherClass implements Serializable {
          SampleClass sampleClass;
    }
    
    public class Ser {
        public static void main(String argv[])
            throws Exception
        {
            SampleClass s = new SampleClass();
            s.name = "name";
            s.fieldName = "fieldName";
    
            AnotherClass a = new AnotherClass();
            a.sampleClass = s;
    
            // serialize the classes to a byte array
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(os);
            oos.writeObject(a);
            oos.close();
    
            // deserialize the classes from the byte array
            ObjectInputStream is
                = new ObjectInputStream(
                        new ByteArrayInputStream( os.toByteArray() ));
            a = (AnotherClass)is.readObject();
            is.close();
    
            // print something
            System.out.println(a.sampleClass.name);
        }
    }
    

    您能否发布导致问题的确切代码?

    【讨论】:

    • 请查看编辑区域。我正在使用 Hibernate SQL 从表中获取值。 session.createQuery("来自 Aemploye")。这将使用表中的值填充 Aemploye 和 Aadress bean。现在我可以访问 Aemploye bean 中的值,但是,当我尝试访问 Aadress 时,它显示上述错误...
    【解决方案3】:

    除非您有一些非常不寻常的框架来执行此操作,否则使用 getter 不涉及序列化。

    我建议您查看确切的堆栈跟踪(并将其发布在问题中)并查看异常实际发生的位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2015-07-25
      相关资源
      最近更新 更多