2

システムには、リソースのキーと値のペアを格納するテーブルがあります。値を格納するための2つの列があります。小さい値の場合はVARCHAR列、大きい値の場合はCLOB。Java側では、これらはStandardResourceBundleValueまたはLargeResourceBundleValueの2つのクラスのいずれかにインスタンス化され、1つのテーブルでそれらを区別するために識別子列が使用されます。

<discriminator type="string">
    <column name="RESOURCE_TYPE" length="20" index="XIE1CPD_RESOURCE_BUNDLE_L_V"/>
</discriminator>
...
<subclass name="StandardResourceBundleValue" discriminator-value="STANDARD">
    <property name="messageValue" type="string" column="STD_MSG_VALUE" length="400"/>
</subclass>
<subclass name="LargeResourceBundleValue" discriminator-value="LARGE">
    <property name="messageValue" type="materialized_clob" column="LARGE_MSG_VALUE"/>
</subclass>

楽しい部分は次のとおりです。キーの値が最初は小さく(そしてStandardResourceBundleValueとして保持され)、値がVARCHARよりも大きい値に変わる場合は、それをStandardResourceBundleValueに変換する方法が必要です。これが発生しているコードでは、StandardResourceBundleValueを削除して、LargeResourceBundleValueを作成することはできません。これは、制約違反の原因となるためです。

私たちがやりたいのは、その識別子列のプロパティを定義することです。これにより、基本クラスはオブジェクト内のその値を変更するメソッドを持つことができるため、再度永続化されると、CLOBに値が保存されます。

<property name="resourceType" type="string">
    <column name="RESOURCE_TYPE"/>
</property>    

テーブルを作成しようとすると、次のエラーが発生します。

エンティティのマッピングで繰り返される列:com.foo.resourcebundle.LargeResourceBundleValue列:RESOURCE_TYPE(insert = "false" update = "false"でマッピングする必要があります)

明らかに私が何をしようとしているのか理解していませんが、それを行う方法があるべきであることは理にかなっています。では、どのようにしてディスクリミネーターフィールドをプロパティとして公開しますか?

ありがとう。

4

1 に答える 1

2

あなたはそれをすることはできません。オブジェクトにはタイプがあり、あるタイプから別のタイプに切り替えることはできません。これがJavaの仕組みです。

ここに2種類のエンティティを含めるべきではないと思います。識別子を基本的な列挙型列として格納し、この列挙型の値に基づいてvarcharまたはclob列のプロパティの値を格納/フェッチしてみませんか。すべてがオブジェクトに透過的にカプセル化されていることを確認してください。そうすれば、発信者にとってもすべてが簡単になります。列挙型フィールドは公開することさえできませんでした。これを使用して実装しgetMessageValue()(適切な列から値を取得し)、setMessageValue()が呼び出されたときに、新しい値の長さに基づいてその値を変更します。

于 2012-01-11T21:53:06.190 に答える