我有一个包含一个字段的表,可以根据描述符值(Project,TimeKeep或CostCenter)指向其他3个表中的一个外键。通常这是通过子类实现的,我想知道是否我在下面的内容将起作用。注意子类名称与父类相同,noteObject属性映射到java.lang.Object 类型的实例变量,因此它应该接受一个Project,只要我们转换为正确的类型,TimeKeep或CostCenter对象.hibernate会允许这个吗?谢谢。
<hibernate-mapping package="com.tlr.finance.mappings">
<class name="AdminNotes" table="admin_notes">
<id name="adminNoteId" column="admin_note_id" type="integer">
<generator class="identity" />
</id>
<discriminator column="note_type" type="string" />
<!-- make this property an enumerated type. It is the discriminator -->
<property name="adminNoteType" column="note_type" type="string" not-null="true" />
<property name="adminNote" column="note" type="string" not-null="true" />
<property name="adminNoteAdded" column="note_date" type="timestamp"
not-null="true" />
<subclass name="AdminNotes" discriminator-value="project" >
<many-to-one name="noteObject" column="object_id" class="PsData" /><!-- Project -->
</subclass>
<subclass name="AdminNotes" discriminator-value="user" >
<!-- rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="Timekeep" /><!-- user -->
</subclass>
<subclass name="AdminNotes" discriminator-value="costCenter" >
<!-- rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="CostCenter" /><!-- cost center -->
</subclass>
</class>
</hibernate-mapping>
答案 0 :(得分:9)
判别器用于在单个表中存储类层次结构。你有什么是一个有多重含义的单一课程。
元素是 多态持久性所必需的 使用table-per-class-hierarchy 映射策略并声明一个 表的鉴别器列。该 鉴别器列包含标记 告诉持久层的值 要为a实例化的子类 特别的一行。
我认为您不能为每个不同的含义使用单个AdminNote类。在数据库级别使用鉴别器来帮助区分一个子类 - 它实际上不是java对象模型的一部分。
您需要定义多个AdminNote子类,每个子类用于每个鉴别器值。
答案 1 :(得分:1)
通常,如果在子类中将discriminator-value指定为整数,则会出现错误
无法使用(...)
将鉴别器值'TYPE'格式化为SQL字符串
如果您希望将鉴别器用作整数值,则首先需要通过在class元素中设置discriminator-value属性将其指定为基类:
<class name="AdminNotes" table="admin_notes" abstract="true" discriminator-value= "-1">
这取代了在未找到值时鉴别器是类名的默认行为。
<hibernate-mapping package="com.tlr.finance.mappings">
<class name="AdminNotes" table="admin_notes" abstract="true" discriminator-value= "-1">
<id name="adminNoteId" column="admin_note_id" type="integer">
<generator class="identity" />
</id>
<discriminator column="note_type" type="integer" />
<!-- Make this property an enumerated type. It is the discriminator. -->
<property name="adminNoteType" column="note_type" type="string" not-null="true" />
<property name="adminNote" column="note" type="string" not-null="true" />
<property name="adminNoteAdded" column="note_date" type="timestamp"
not-null="true" />
<subclass name="AdminNotes" discriminator-value="0" entity-name="project">
<many-to-one name="noteObject" column="object_id" class="PsData" /><!-- Project -->
</subclass>
<subclass name="AdminNotes" discriminator-value="1" entity-name="user">
<!-- Rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="Timekeep" /><!-- user -->
</subclass>
<subclass name="AdminNotes" discriminator-value="2" entity-name="costCenter">
<!-- Rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="CostCenter" /><!-- cost center -->
</subclass>
</class>
</hibernate-mapping>
答案 2 :(得分:0)
AFAIK,如果使用实体名称,则可以为子类映射重用Java类名。
尝试下面的映射。这里的超类映射本身就是抽象的。子类对每个子类使用相同的Java类和实体名称。您可能需要将entity-name放入超类映射。但是,我个人会为每个子类映射使用单独的Java子类,因为当您需要通过Session API持久保存对象时,您必须提供实体名称,或者实现实体名称解析。 Tuplizer(Hibernate 3.3.2)基于adminNoteType字段。
<hibernate-mapping package="com.tlr.finance.mappings">
<class name="AdminNotes" table="admin_notes" abstract="true">
<id name="adminNoteId" column="admin_note_id" type="integer">
<generator class="identity" />
</id>
<discriminator column="note_type" type="string" />
<!-- Make this property an enumerated type. It is the discriminator. -->
<property name="adminNoteType" column="note_type" type="string" not-null="true" />
<property name="adminNote" column="note" type="string" not-null="true" />
<property name="adminNoteAdded" column="note_date" type="timestamp"
not-null="true" />
<subclass name="AdminNotes" discriminator-value="project" entity-name="project">
<many-to-one name="noteObject" column="object_id" class="PsData" /><!-- Project -->
</subclass>
<subclass name="AdminNotes" discriminator-value="user" entity-name="user">
<!-- rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="Timekeep" /><!-- user -->
</subclass>
<subclass name="AdminNotes" discriminator-value="costCenter" entity-name="costCenter">
<!-- rename timekeep to user -->
<many-to-one name="noteObject" column="object_id" class="CostCenter" /><!-- cost center -->
</subclass>
</class>
</hibernate-mapping>
答案 3 :(得分:0)
您应该考虑使用<any/>
映射类型,而不是尝试使用继承功能来获取对正确类的引用,而是使用note_type
映射类型来确定object_id
的类型1}}正在引用,因此将noteObject
值设置为正确的对象引用。
有关<any/>
的详细信息,请参阅Any type mappings文档中的“NHibernate”和博客文章 NHibernate Mapping 。