Figured it out...

    <composite-id>
      <key-property name="Id" />
      <key-many-to-one name="Playlist" column="PlaylistId"/>
    </composite-id>

On Tuesday, April 2, 2013 10:47:29 PM UTC+1, Sean Anderson wrote:
>
> I'm hoping not to argue semantics and "you should not use a composite key" 
> with this post. I understand the implications of composite key use, but 
> believe it to be best suited for my task at hand.
>
> I have the following in "PlaylistItem.hbm.xml:"
>
> <?xml version="1.0" encoding="utf-8" ?><hibernate-mapping 
> xmlns="urn:nhibernate-mapping-2.2" assembly="Streamus" 
> namespace="Streamus.Backend.Domain">
>
>   <class name="PlaylistItem" table="[PlaylistItems]" lazy="false" >
>     <composite-id>
>       <key-property name="Id" />
>       <key-property name="PlaylistId"/>
>     </composite-id>
>
>     <property name="Title" not-null="true" />
>
>     <many-to-one name="Playlist" column="PlaylistId"/>
>   </class>
> </hibernate-mapping>
>
> which corresponds with the following class:
>
> [DataContract]public class PlaylistItem{
>     [DataMember(Name = "playlistId")]
>     public Guid PlaylistId
>     {
>         get { return Playlist.Id; }
>         set { Playlist.Id = value; }
>     }
>
>     public Playlist Playlist { get; set; }
>
>     [DataMember(Name = "id")]
>     public Guid Id { get; set; }
>
>     //  Store Title on PlaylistItem as well as on Video because user might 
> want to rename PlaylistItem.
>     [DataMember(Name = "title")]
>     public string Title { get; set; }
>
>     public PlaylistItem()
>     {
>         //  Id shall be generated by the client. This is OK because it is 
> composite key with 
>         //  PlaylistId which is generated by the server. 
>         Id = Guid.Empty;
>         Title = string.Empty;
>     }
>
>     private int? _oldHashCode;
>     public override int GetHashCode()
>     {
>         // Once we have a hash code we'll never change it
>         if (_oldHashCode.HasValue)
>             return _oldHashCode.Value;
>
>         bool thisIsTransient = Equals(Id, Guid.Empty);
>
>         // When this instance is transient, we use the base GetHashCode()
>         // and remember it, so an instance can NEVER change its hash code.
>         if (thisIsTransient)
>         {
>             _oldHashCode = base.GetHashCode();
>             return _oldHashCode.Value;
>         }
>         return Id.GetHashCode();
>     }
>
>     public override bool Equals(object obj)
>     {
>         PlaylistItem other = obj as PlaylistItem;
>         if (other == null)
>             return false;
>
>         // handle the case of comparing two NEW objects
>         bool otherIsTransient = Equals(other.Id, Guid.Empty);
>         bool thisIsTransient = Equals(Id, Guid.Empty);
>         if (otherIsTransient && thisIsTransient)
>             return ReferenceEquals(other, this);
>
>         return other.Id.Equals(Id);
>     }}
>
>
> This clearly generates an exception with NHibernate because the property 
> "PlaylistId" is referenced through the composite key definition as well as 
> in the many-to-one definition. I am obstinate about using PlaylistId as 
> part of the composite key. I would also like to leverage as much of 
> NHibernate's built-in capabilities in order to preserve data integrity.
>
> I've implemented the following as a work-around, but I am not happy with 
> my change. I am not using NHibernate's ability to automatically dehydrate 
> Playlist when loading a PlaylistItem:
>
> public Guid PlaylistId{
>     get
>     {
>         return Playlist == null ? Guid.Empty : Playlist.Id;
>     }
>     set
>     {
>         if (Playlist == null || Playlist.Id != value)
>         {
>             Playlist = new PlaylistDao().Get(value);
>         }
>     }}
>
> in addition to this change, I remove <many-to-one name="Playlist" column=
> "PlaylistId"/>
>
> This works as expected. Whenever NHibernate dehydrates the PlaylistId via 
> the composite key, PlaylistItem's Playlist property is set. However, the 
> code obviously smells. I am wondering -- do I have any options here? Or, is 
> this an unsupported scenario in NHibernate?
>
> Thanks
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nhusers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to