I have a case where I have one table that uses the Table per class hierarchy (Content, with ContentType1 and ContentType2 as subclasses), and another normal table (Category). These classes have a many to many relationship using a third mapping table. The basic relationship works, but I have had problems in a couple of cases.
I first noticed the problem when I attempted to load ContentType1 using a filter. The following is the code I used:
Collection list = hibernateSession.createFilter( category.getContentType1s(), "order by this.score desc" )
.list();
The problem I noticed is that when I execute this code, the discriminator value for ContentType1 is not included in the query, so all rows from the Content table are loaded, not just those of the correct subclass.
To work around this issue, I just put the discriminiator in the where clause for the filter, although it seems like this should be automatic.
Collection list = hibernateSession.createFilter( category.getContentType1s(), "where this.itemType = 1 order by this.score desc" )
.list();
This workaround seemed to be ok, but I ran into the problem again when I attempted to call the hibernateSession.delete( ContentType1 ) method. I got the following Hibernate error:
net.sf.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: ContentType2 (loaded object was of wrong class).
I don't know why it was loading a class of ContentType2 when I was deleting ContentType1, but it seems to me it is probably related to the first issue where the discriminator is left out of the where clause in the generated code.
Hibernate version: 2.1.6
Mapping documents:
<Class name="Category">
...
<set name="contentType1s" table="content_item_category" lazy="true" cascade="all">
<key column="category_id"/>
<many-to-many class="ContentType1" column="content_item_id"/>
</set>
<set name="contentType2s" table="content_item_category" lazy="true" cascade="all">
<key column="category_id"/>
<many-to-many class="ContentType2" column="content_item_id"/>
</set>
...
</Class>
<class name="ContentItem" discriminator-value="0">
...
<discriminator force="true" column="item_type" type="integer"/>
...
<set name="categories" table="content_item_category" lazy="true" cascade="all">
<key column="content_item_id"/>
<many-to-many class="Category" column="category_id"/>
</set>
...
<subclass name="ContentType1" discriminator-value="1">
</subclass>
<subclass name="ContentType2" discriminator-value="2">
</subclass>
...
</class>
Name and version of the database you are using: MySQL 4.0.12
|