Hey,
So, I messed around with marking my Video entity as lazy, but I think it's
fruitless. My server is just a hub for passing data to clients. As such, I
serialize my Video entities pretty much right after retrieval.
Serialization requires loading the entity... resulting in the same issue.
Sean
On Monday, July 1, 2013 10:15:52 AM UTC-7, Sean Anderson wrote:
>
> Hey guys,
>
> I've hit a snag while working with NHibernate and I'm not sure if the
> problem is incredibly trivial or incredibly complex. Naturally, I'm hoping
> for the former. Here's an explanation of my scenario:
>
> I have an immutable entity, Video, which has an assigned ID:
>
> <class name="Video" table="[Videos]" lazy="false" mutable="false">
> <id name="Id" length="11" type="String">
> <generator class="assigned"></generator>
> </id>
>
> <property name="Title" not-null="true" />
> <property name="Duration" not-null="true" />
> <property name="Author" not-null="true" /></class>
>
> I then create and save two detached Video entities which have the same ID.
> NHibernate throws a NonUniqueObjectException when I attempt to save the
> second Video. Here's a failing test case:
>
> public void CreateItem_VideoAlreadyExists_ItemCreatedVideoNotUpdated(){
> // Save this Video before continuining so that it exists before adding
> the PlaylistItem.
> string randomVideoId = Guid.NewGuid().ToString().Substring(0, 11);
> var videoNotInDatabase = new Video(randomVideoId, "Video", 999, "Author");
> VideoManager.Save(videoNotInDatabase);
>
> // Change the title for videoInDatabase to check that cascade-update
> does not affect title. Videos are immutable.
> const string videoTitle = "A video title";
> var videoInDatabase = new Video(randomVideoId, videoTitle, 999, "Author");
>
> // Create a new PlaylistItem and write it to the database.
> string title = videoInDatabase.Title;
> var playlistItem = new PlaylistItem(title, videoInDatabase);
>
> Playlist.AddItem(playlistItem);
> PlaylistManager.SavePlaylistItem(playlistItem);
>
> // Remove entity from NHibernate cache to force DB query to ensure
> actually created.
> NHibernateSessionManager.Instance.Clear();
>
> // Ensure that the Video was NOT updated by comparing the new title to
> the old one.
> Video videoFromDatabase = VideoDao.Get(randomVideoId);
> Assert.AreNotEqual(videoFromDatabase.Title, videoTitle);
>
> // Ensure that the PlaylistItem was created.
> PlaylistItem itemFromDatabase = PlaylistItemDao.Get(playlistItem.Id);
> Assert.NotNull(itemFromDatabase);
>
> // Pointers should be self-referential with only one item in the
> Playlist.
> Assert.AreEqual(itemFromDatabase.NextItem, itemFromDatabase);
> Assert.AreEqual(itemFromDatabase.PreviousItem, itemFromDatabase);}
>
> This test case fails on "PlaylistManager.SavePlaylistItem" which is just a
> transaction wrapper for calling NHibernate's ISession.Save.
>
> I understand why (and my options, such as Merge, Evict, or Refresh) but I
> feel like an option is missing. My Video entity is immutable, so it cannot
> be updated. NHibernate already knows about the Video because it is in its
> cache, so it cannot be inserted. As such, even though NHibernate throws a
> NonUniqueObjectException… in reality, no operation can occur on the entity.
> I have been unable to find a way to express this to NHibernate.
>
> I am opposed to having to refresh the Video entity because it is the child
> of a large hierarchy of parent entities. Iterating to the bottom of the
> hierarchy for each entity in the collection, just to call Refresh on a
> Video, seems like an extremely bad design decision.
>
> I understand that if I used a Versioning system that NHibernate would be
> able to determine that the two entities are unique. However, I do not wish
> for them to be treated as such. I only want one Video with a given ID to be
> written to my table.
>
> Full details can be found here:
> http://stackoverflow.com/questions/17396362/nonuniqueobjectexception-thrown-after-client-attempts-to-save-the-same-item-twic
>
>
> Do I have an architectural flaw? Am I missing a simple keyword? Or is this
> 'hard' for other reasons?
>
> Thanks for taking the time to read. Cheers,
>
> Sean Anderson
>
--
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.
For more options, visit https://groups.google.com/groups/opt_out.