Performing updates in OnPostUpdate event causes enumeration error

Description

Executing following code:

void IPostUpdateEventListener.OnPostUpdate(PostUpdateEvent @event)
{
/*

  • Getting left and right ommited
    */
    @event.Session.CreateSQLQuery("update categories c set isbranchactive = 1 where c.lft >= :lft and c.rgt <= :rgt")
    .SetInt64("lft", left)
    .SetInt64("rgt", right)
    .ExecuteUpdate();
    }

when commiting a transaction results with:

[InvalidOperationException: Collection was modified; enumeration operation may not execute.]
System.ThrowHelper.ThrowInvalidOperationException(ExceptionResourceresource) +56
System.Collections.Generic.Enumerator.MoveNextRare() +58
System.Collections.Generic.Enumerator.MoveNext() +93
NHibernate.Engine.ActionQueue.ExecuteActions(IList list) +149
NHibernate.Engine.ActionQueue.ExecuteActions() +32
NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSourcesession) +253
NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEventevent) +97
NHibernate.Impl.SessionImpl.Flush() +275
NHibernate.Transaction.AdoTransaction.Commit() +236

I looked into the ExecuteActions(...) and replaced foreach enumeration
with a regular for loop.
Everything seems to work just fine. Tests are passing (NH
2.1.1, 2.1.2 and 3 [current trunk rev 5180]).

Environment

None

Attachments

1

is related to

Activity

Show:

Julian Maughan September 13, 2010 at 9:35 AM

Thanks Filip. I reviewed and committed your patch (rev. 5183) with the following comment: "Fixed bug where an IPostUpdateEventListener.OnPostUpdate event causes an enumeration error in ActionQueue.ExecuteActions. In the event, an ExecuteUpdate criteria statement causes a flush to occur during a flush already initiated by transaction commit. This results in an earlier-than-expected call to ActionQueue.ClearFromFlushNeededCheck, resetting its list of updates before it has finished iterating them (ref. NH-2322). Thanks Filip Zawada for the solution."

I am going to spend a bit more time with this issue to see if there is a better solution. Also, there are some Hibernate minor improvements that I would like to introduce.

Filip Zawada September 6, 2010 at 6:58 PM

Commiter, please check for potential:
TearDown Error : NHibernate.Test.NHSpecificTest.NH2322.Fixture.ShouldNotThrowWhenCommitingATransaction
TearDown : NUnit.Framework.AssertionException : Test didn't clean up after itself. session closed: True database cleaned: False connection closed: True

I couldn't get it passing even though the test does't leave any artifacts in the DB.
Except for that one - I think it works.

Fixed

Details

Assignee

Reporter

Components

Fix versions

Affects versions

Priority

Who's Looking?

Open Who's Looking?

Created September 6, 2010 at 2:47 PM
Updated September 4, 2017 at 1:28 PM
Resolved September 18, 2010 at 5:40 AM
Who's Looking?