Hi,
I'm having problems with collections of inherited classes in hibernate.
Let's say I have a superclass named
Content, and subclasses for two different types of content;
Image and
Article.
I also have a class named
Document, which contains a collection of Content.
My problem is that when I add a new Content object to the collection my Document object, and then save the Document object using hibernate, the database will not have the new row in the table corresponding to the Content subclass. I must be making some mistake.
Database design is as follows:
Code:
DOCUMENT
id
name
DOCUMENT_CONTENT
id
document_id
IMAGE
id (same as DOCUMENT_CONTENT.id)
url
ARTICLE
id (same as DOCUMENT_CONTENT.id)
text
As you can see, the DOCUMENT_CONTENT.id is the same as IMAGE.id and ARTICLE.id. In other words, some sample data can look like:
Code:
DOCUMENT
id name
1 A sample document
DOCUMENT_CONTENT
id document_id
4 1
5 1
IMAGE
id url
4 C:/images/an_image.jpg
ARTICLE
id text
5 This is an article...
I don't know if this is the best database design.
If I insert these rows by hand, using a query analyzer, and use hibernate to get the Document with id 1, I will get an object with a collection of the correct types; one Image and one Article. Fine and dandy. However, if I would add for example a new Article instance to a Document object and save it, the
DOCUMENT_CONTENT table gets updated correctly, but no new rows gets created in the
ARTICLE table.
The collection in the Document class is of type
IList. Other than that, the code implementation of the classes is not important; they are just entites with virtual properties (corresponding to the database design) and nothing more.
I think there's something wrong with my mapping. I'm using table-per-subclass mapping. See how it looks today below (note that the Image and Article classes does not have a mapping. When I tried adding mapping for them, I got an error).
Code:
<!-- MAPPING FOR Document CLASS -->
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="Project.Models.Entities" assembly="Project">
<class name="Document" table="DOCUMENT">
<id name="ID">
<column name="id" sql-type="int" not-null="true"/>
</id>
<property name="Name">
<column name="title" length="256" not-null="true" />
</property>
<bag name="ContentCollection" table="DOCUMENT_CONTENT" lazy="false">
<key column="document_id"></key>
<many-to-many class="Content" column="id"></many-to-many>
</bag>
</class>
</hibernate-mapping>
<!-- MAPPING FOR Content CLASS -->
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="Project.Models.Entities" assembly="Project">
<class name="Content" table="DOCUMENT_CONTENT">
<id name="ID">
<column name="id" sql-type="int" not-null="true"/>
</id>
<joined-subclass name="Image" table="IMAGE">
<key column="id"/>
<property name="Url" column="url"/>
</joined-subclass>
<joined-subclass name="Article" table="ARTICLE">
<key column="id"/>
<property name="Text" column="text"/>
</joined-subclass>
</class>
</hibernate-mapping>