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
-~----------~----~----~----~------~----~------~--~---

Reply via email to