将鉴别器列公开为hbm文件中的属性

时间:2012-01-11 21:42:22

标签: hibernate subclass discriminator

我们的系统中有一个存储资源键/值对的表。存储该值的列有两列; VARCHAR列表示较小的值,CLOB表示较大的值。在Java方面,它们被实例化为两个类之一,StandardResourceBundleValue或LargeResourceBundleValue,并且鉴别器列用于在一个表中区分它们:

<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”映射)

显然它不明白我想要做什么,但是应该有一种方法可行。那么如何将一个鉴别器字段公开为一个属性呢?

感谢。

1 个答案:

答案 0 :(得分:2)

你做不到。对象具有类型,并且无法从一种类型切换到另一种类型。这就是Java的工作原理。

我认为你不应该在这里有两种类型的实体。为什么不将鉴别器存储为基本枚举列,并根据此枚举的值在varchar或clob列中存储/获取属性的值。确保所有内容都透明地封装在对象中,即使对于呼叫者来说,一切都会更容易。枚举字段甚至不能公开。您可以使用它来实现getMessageValue()(从适当的列中获取值),并根据新值的长度在调用setMessageValue()时更改其值。