Oskar, Thank-you so much!
I have re-factored so that my Project only has 1 collection (of ProjectMedia), and each list (Videos and Images) returns either a list of ProjectVideo or ProjectImage objects. It is still not perfect, as it is not as "readable" as it was having two separate collections, but the functionality is there and that is the main thing. Thanks again, Dan. On Jun 29, 2:40 pm, Oskar Berggren <[email protected]> wrote: > 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 > > ... > > read more » --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
