Let's say that I have a class/table called Images
that, as it stands right now, is bound in a manner similar to this:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="Domain.Image, Domain" table="Images">
<id name="id" column="ImageID" access="field" unsaved-value="0">
<generator class="identity" />
</id>
<!-- other properties -->
<property name="AssociatedObjectID" column="AssociatedObjectID" />
<property name="AssociatedObjectType" column="AssociatedObjectType" />
</class>
</hibernate-mapping>
Up until this point, this schema has worked, because a image was only associated with one object, so I could keep that reference without a discriminator.
However, now I wish to have a collection of these images on another entity called a PhotoShoot
. Each PhotoShoot
can have several images.
Is there a way to bind a collection such that I can have a List<Image>
within PhotoShoot
without extracting a base class and using the table-per-hierarchy inheritance pattern?
And if not, is table-per-hierarchy really the best way to go here? I hate to create subclasses, especially since there is nothing that needs to be abstracted from the Image
entity.
I would map this as an IList<Images> property on PhotoShoot, mapped via a join table (many-to-many).
If the ordering of the list is important, map as a list otherwise as a bag. I have included both mappings.
<class name="Domain.PhotoShoot, Domain" table="PhotoShoot">
<id name="id" column="PhotoShootId" access="field" unsaved-value="0">
<generator class="identity" />
</id>
<!-- other properties -->
<!-- unordered list -->
<bag name="Images" table="PhotoShoot_Image" fetch="join" cascade="all-delete-orphan">
<key column="PhotoShootId"/>
<many-to-many class="Domain.Image, Domain" column="ImageId" />
</bag>
<!-- ordered list -->
<list name="Images" table="PhotoShoot_Image" fetch="join" cascade="all-delete-orphan">
<key column="PhotoShootId"/>
<imdex column="position" />
<many-to-many class="Domain.Image, Domain" column="ImageId" />
</list>
</class>
public class PhotoShoot
{
IList<Image> Images { get; set; }
}
Using @ddango's original class mapping we could instead do the following.
<class name="Domain.PhotoShoot, Domain" table="PhotoShoot">
<bag name="Images" table="Image" fetch="join" where="AssociatedObjectType='PhotoShoot'">
<key column="AssociatedObjectId"/>
<one-to-many class="Domain.Image, Domain" />
</bag>
</class>
You could use a many-to-many mapping tables, rather than putting the AssociatedObjectId/Type in your image class/table. Many-to-manys are a little trickier to work with in Hibernate, but give you some extra flexibility.
Image
-----
Id (PK)
OtherProp1
OtherProp2
Attachment
----------
Id (PK)
OtherProp1
AttachmentImage (many-to-many between Attachment and Images)
---------------
ImageId (PK, FK to Image.Id)
AttachmentId (PK, FK to Image.Id)
PhotoShoot
----------
Id (PK)
OtherProp1
-- AttachmentId (if PhotoShoot has only a single attachment)
PhotoShootAttachment (if Photoshoot can have many attachments)
--------------------
ImageId (PK, FK to Image.Id)
AttachmentId (PK, FK to Attachment.Id)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.