Your usecase seem a bit unusual. Shouldn't the point of polymorphism would be to avoid multiple implementations of AddImage/Video, multiple collections, etc? Anyway, for your second attempt, look into adding where-clauses to your bag-elements (http://nhforge.org/doc/nh/en/index.html#collections-mapping).
Alternatively map it as one collection, then have convenience properties in your class to filter out only images and only videos if this is a common usecase. Alternatively, have you considered table-per-class-hierarchy? This avoids repeating your common columns. As for your original method, I don't know if it should work or why it doesn't, I'm afraid. Maybe it isn't supported, or maybe there is something simple that needs to be changed. Or maybe it is a bug. /Oskar 2009/6/29 Dan <[email protected]>: > > Ok, since no-one is willing to help, I've done more Googling and > discovered that you should map the polymorphic association in the > collection when using the table-per-subclass strategy, and NHibernate > will take care of the rest. So, now I have this: > > ProjectMedia - base class, abstract > ProjectVideo - concrete, inherits from ProjectMedia. > ProjectImage - concrete, inherits from ProjectMedia. > > Project has a list of Videos, of type ProjectMedia. > Project has a list of Images, of type ProjectMedia. > > The project class is as follows: > > public class Project > { > // basic properties > public virtual int ProjectId { get; private set; } > ... other properties... > > public virtual IList<ProjectMedia> Images { get; set; } > public virtual IList<ProjectMedia> Videos { get; set; } > > public Project() > { > Images = new List<ProjectMedia>(); > Videos = new List<ProjectMedia>(); > } > > public virtual void AddImage(ProjectImage image) > { > image.Project = this; > Images.Add(image); > } > > public virtual void AddVideo(ProjectVideo video) > { > video.Project = this; > Videos.Add(video); > } > } > > And the mapping files for all this are: > > <class name="Project" table="Projects"> > <id name="ProjectId"> > <generator class="native" /> > </id> > > <!-- other properties here --> > > <bag name="Images" > cascade="all-delete-orphan" > inverse="true"> > <key column="ProjectId" /> > <one-to-many class="ProjectMedia" /> > </bag> > > <bag name="Videos" > cascade="all-delete-orphan" > inverse="true"> > <key column="ProjectId" /> > <one-to-many class="ProjectMedia" /> > </bag> > </class> > > And the ProjectMedia mapping as follows: > > <class name="ProjectMedia" table="ProjectMedia"> > <id name="ProjectMediaId"> > <generator class="native" /> > </id> > > <property name="MediaPath" /> > <property name="ThumbnailPath" /> > > <many-to-one > name="Project" > column="ProjectId" > class="Project" /> > > <joined-subclass > name="ProjectImage" > table="ProjectImage" lazy="false"> > <key column="ProjectMediaId" /> > <property name="ImageCredit" /> > <property name="ImageCaption" /> > </joined-subclass> > > <joined-subclass > name="ProjectVideo" > table="ProjectVideo" lazy="false"> > <key column="ProjectMediaId" /> > <property name="CreditLine" /> > </joined-subclass> > > </class> > > With all of this in place, the saving of the Project with associated > Images and Videos works fine. The problem is, once the Project has > been persisted and then re-loaded, both the collections contain all > the previously-added ProjectImages and ProjectVideos, as opposed to > the Videos collection only containing ProjectVideos and the Images > collection only containing ProjectImages. > > Can anyone help with this at all? I'm starting to lose faith in > NHibernate and getting very close to going back to using good old- > fashioned ADO and Stored Procedures for my CRUD operations. > > Thanks, > Daniel. > > On Jun 23, 12:23 pm, Dan <[email protected]> wrote: >> I'm having trouble with a joined-subclass mapping within my domain >> model using NHibernate. >> >> I have an abstract class "ProjectMedia" with some properties, and 2 >> concrete classes that inherit from this class, "ProjectImage" and >> "ProjectVideo". These map to tables ProjectMedia, ProjectImage and >> ProjectVideo, respectively, in the database. >> >> I am using the "Table per subclass" mapping scenario, where the 3 >> tables have a shared primary/foreign key so that they can be joined to >> get the concrete data for each object. >> >> Along with this, I have a "Project" class, which has a list of images >> and videos, which map to ProjectImage and ProjectVideo. Here are my >> mappings: >> >> For the Project class: >> >> <class name="Project" table="Projects" lazy="true"> >> <id name="ProjectId"> >> <generator class="native" /> >> </id> >> >> <property name="ProjectDate" not-null="true" /> >> ... >> <property name="PDF" not-null="false" /> >> >> <bag name="Images" table="ProjectMedia" >> cascade="all-delete-orphan" >> inverse="true"> >> <key column="ProjectId" /> >> <one-to-many class="ProjectImage" /> >> </bag> >> >> <bag name="Videos" table="ProjectMedia" >> cascade="all-delete-orphan" >> inverse="true"> >> <key column="ProjectId" /> >> <one-to-many class="ProjectVideo" /> >> </bag> >> </class> >> >> For the ProjectMedia/ProjectVideo/ProjectImage classes: >> >> <class name="ProjectMedia" table="ProjectMedia" lazy="true"> >> <id name="ProjectMediaId"> >> <generator class="native" /> >> </id> >> >> <property name="MediaPath" /> >> <property name="ThumbnailPath" /> >> >> <many-to-one name="Project" column="ProjectId" >> class="IdMedia.Data.Domain.Project, IdMedia.Data" not-null="true" /> >> >> <joined-subclass >> extends="ProjectMedia" >> name="ProjectImage" >> table="ProjectImage"> >> <key column="ProjectImageId" /> >> <property name="ImageCredit" /> >> <property name="ImageCaption" /> >> </joined-subclass> >> >> <joined-subclass >> extends="ProjectMedia" >> name="ProjectVideo" >> table="ProjectVideo"> >> <key column="ProjectVideoId" /> >> <property name="CreditLine" /> >> </joined-subclass> >> </class> >> >> Saving and loading of the project work fine with images and videos >> added to the collection. >> >> However, when I try to access either the Image or Video collections, I >> get this error: >> >> NHibernate.Exceptions.GenericADOException : could not initialize a >> collection: [IdMedia.Data.Domain.Project.Images#163][SQL: SELECT >> images0_.ProjectId as ProjectId1_, images0_.ProjectImageId as >> ProjectI1_1_, images0_.ProjectImageId as ProjectM1_1_0_, >> images0_1_.MediaPath as MediaPath1_0_, images0_1_.ThumbnailPath as >> Thumbnai3_1_0_, images0_1_.ProjectId as ProjectId1_0_, >> images0_.ImageCredit as ImageCre2_2_0_, images0_.ImageCaption as >> ImageCap3_2_0_ FROM ProjectImage images0_ inner join ProjectMedia >> images0_1_ on images0_.ProjectImageId=images0_1_.ProjectMediaId WHERE >> images0_.ProjectId=?] >> >> ----> System.Data.SqlClient.SqlException : Invalid column name >> 'ProjectId'. >> Invalid column name 'ProjectId'. >> >> It seems that NHibernate is setting up the join for the joined- >> subclasses fine, but it has the tables in the join specified in the >> wrong order, therefore, ProjectId (the foreign key to the Projects >> table) is being referenced incorrectly. >> >> Can anyone help with this? I cannot see a reason why this will not >> work the way I have defined the mappings. I have searched everywhere, >> but cannot find an answer. This method was even taken from the book >> "NHibernate in Action", so I cannot understand why it is not working. >> >> I know I can get around it using 1 table per concrete class, but I >> would prefer to do it using joined subclasses, as this saves from data >> repetition. >> >> Thanks, >> Dan. > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "nhusers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nhusers?hl=en -~----------~----~----~----~------~----~------~--~---
