I have a table with one field that can point to a foreign key in one of 3 other tables based on what the descriminator value is (Project, TimeKeep, or CostCenter. Usually this is implemented with subclasses, and I am wondering if what I have below will work. Note the subclass name is the same as the parent class and the noteObject property is mapped to an instance variable of type java.lang.Object so it should accept either a Project, TimeKeep or CostCenter object as long as we cast to the correct type. Will hibernate allow this? Thanks.
<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>
Discriminators are used for storing class hierarchies in a single table. What you have there is a single class with multiple meanings.
http://docs.jboss.org/hibernate/core/3.5/reference/en-US/html/mapping.html#mapping-declaration-discriminator
The element is required for polymorphic persistence using the table-per-class-hierarchy mapping strategy and declares a discriminator column of the table. The discriminator column contains marker values that tell the persistence layer what subclass to instantiate for a particular row.
I don't think you'll be able to use a single AdminNote class for each of those different meanings. The discriminator is used at the database level to help distinguish one subclass from another - it's not actually part of the java object model.
You'll need to define multiple subclasses of AdminNote, one for each discriminator value.
Normally, if you specify the discriminator-value as integer in subclass, you get the error
Could not format discriminator value 'TYPE' to SQL string using the (...)
If you wish to use the discriminator as an integer value, you need to first of all specify it for the base class as an integer by setting the discriminator-value attribute in the class element:
<class name="AdminNotes" table="admin_notes" abstract="true" discriminator-value= "-1">
This replaces the default behavior where the discriminator is a class name when a value is not found.
<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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With