0

データベースに保持したい Java クラスがあります。

public class ClassA implements Serializable {
    //
    // other fields not shown
    //

    private ObjectType objectType;  // an enum that indicates the actual class stored in the "object" field
    private Object object;
}

Hibernate マッピング ファイルは次のとおりです。

<hibernate-mapping default-lazy="false">
    <class name="x.y.z.ClassA" table="ClassA">
        <!--
           other properties removed
        -->

        <property name="objectType" column="OBJECTTYPE">
            <type name="org.hibernate.type.EnumType">
                <param name="enumClass">
                    x.y.z.ClassA$ObjectType
                </param>
                <param name="type">12</param>
            </type>
        </property>

        <property name="object" column="OBJECT" type="serializable"/>
    </class>
</hibernate-mapping>

Hibernate を使用して ClassA のインスタンスをデータベースに挿入すると、行が挿入され、"object" フィールドが longblob として定義されていることがわかります。しかし、MySQL Workbench を使用して「object」フィールドのデータを確認すると、データ長が 255 バイトであることがわかります。「オブジェクト」フィールドに格納しようとしているオブジェクトには、合計で 255 文字を超える文字列が含まれています。longblob 列に格納される前に圧縮されていますか?

私が抱えている問題は、挿入した行を照会するために Hibernate を使用しようとしたときです。Hibernate は 0 行を返し、Hibernate ログに次のエラーが表示されます。

8167 [Thread-32] INFO  org.hibernate.type.SerializableType - could not read column value from result set: OBJECT195_0_; could not deserialize

Hibernate が longblob 列に格納するときにオブジェクトが圧縮されていない場合、それが「デシリアライズできませんでした」というエラーの原因であると思います。255 バイトよりも大きいことはわかっていますが、MySQL Workbench は長さが 255 バイトであるため、何らかの理由でオブジェクトが切り捨てられている必要があります。

しかし、オブジェクトが圧縮されている場合、Hibernate は単に java.lang.Object 型であり、実際のオブジェクト型が何であるかを認識していないため、逆シリアル化できない可能性があります。この場合、Hibernate 用のカスタム デシリアライザーを作成する方法はありますか? 実際のオブジェクト タイプは「objectType」フィールドによって示されるため、カスタム デシリアライザは「objectType」フィールドをチェックして、「object」フィールドをデシリアライズする方法を知ることができます。

4

1 に答える 1

0

Hibernate はデフォルトで longblob カラムの最大サイズを 255 バイトに設定することがわかりました。マッピング ファイルの行を次のように変更しました。

<property name="object" column="OBJECT" type="serializable" length="2147483647"/>

これで問題は解決しました。

于 2013-03-16T05:17:33.247 に答える