You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Boris Drajer created an issue — 27th December 2012, 10:04:54:
I haven't been able to reproduce the complete behavior in unit tests, but hopefully this will be enough to find the cause.
The sequence of actions is this:
Load an entity with a lazy one-to-many bag
Add a new (unsaved) object to the yet-uninitialized bag. The add is queued for later.
Initialize the bag with NHibernateUtil.Initialize()
At this point, the collection creates a snapshot of its contents, and the snapshot contains the unsaved object from step 2 - which I believe is wrong.
A consequence of this is that if I --
4. Remove the newly added unsaved object from collection
5. Flush the session
-- I get an exception saying "object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave." The exception is thrown by NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(), and the reason why this happens is that the AbstractPersistentCollection.GetOrphans() method receives this unsaved object in the oldElements collection, which I believe should never happen (oldElements should contain the state present in the database?) This was caused by the incorrect snapshot in the collection in step 3.
I was able to reproduce only the incorrect snapshot in the unit test. The later exception appears in my application but I cannot figure out which combination of mappings triggers it, probably a multiple cascade of delete-orphan relations. In any case, when I reverse the order of steps 2 and 3 - that is, initialize the collection before adding the object - the problem disappears.
I suppose the solution would be to somehow modify the code to create the collection snapshot before the queued actions are replayed, but I have no idea if this is correct or how it could be properly done.
There are two files attached that reproduce the incorrect snapshot. It's a modified version of the existing generic bag test, include it in NHibernate.Test/GenericTest/BagGeneric and run the supplied method.
Environment: .Net framework 3.5 SP1, SQL Server 2005 dialect running on a SQL Server 2008.
As a side note, it seems to me that the exception in the GetEntityIdentifierIfNotUnsaved() method is a bit misplaced, I'm mentioning it here because this is a good illustration why: the method doesn't really know the reason for the error, the message is just a guess. The problem here is not that something needs to be saved or cascaded but that the collection state is corrupt. I think it would be better if the error is handled in a caller method (possibly by catching this exception and providing a better message). This part is related to NH-2070 - I can create a separate issue for this if appropriate.
Adrian Walters added a comment — 20th May 2013, 19:22:18:
We are experiencing a similar issue, where adding and then removing an item to a colleciton causes an exception when NH attempts to flush changes. Is there any estimate when this bug will be addressed?
The text was updated successfully, but these errors were encountered:
Boris Drajer created an issue — 27th December 2012, 10:04:54:
Adrian Walters added a comment — 20th May 2013, 19:22:18:
The text was updated successfully, but these errors were encountered: