History Log and NHibernate Event Listener fails

89 views
Skip to first unread message

Fethi Gürcan

unread,
Apr 10, 2009, 4:58:01 AM4/10/09
to nhusers
Hello,

I'm trying to add some history info about insert,update,delete events.
With log4net, or another way (separate session) it is works. But I'm trying to do it in same transaction with the process.

For that case,

I've created a event listener class;

    public class AuditEventListener : IPostUpdateEventListener,IPostInsertEventListener,IPostDeleteEventListener

And i've created a History entity class.

In the events i've wrote,

             public void OnPostInsert(PostInsertEvent @event)
             {
                    //no history for History type, and prevents recurrence
                    if (@event.Entity.GetType().Equals(typeof(History)))
                            return;
                   
                    History history = new History();
                     .....
                     .....

                    @event.Session.Save(history);
             }


But it seems, I'm breaking the queue action of nHibernate  :(

It is about NHibernate.Engine.ActionQueue class'es ExecuteActions method.

        private void ExecuteActions(IList list)
        {
            foreach (IExecutable executable in list)
                Execute(executable);

            list.Clear();
            session.Batcher.ExecuteBatch();
        }

it throws an InvalidOperationException (Collection was modified; enumeration operation may not execute.).

It is totally understandable issue. (i'd add another action to queue while nhibernate processing the queue)

Do you have any suggestion to do this thing  in another way???

If not,  i can change the code of NHibernate.Engine.ActionQueue.ExecuteActions methods to prevent this error.
(I'm not sure, if i change, it will throws another exception in another method.)
(Changing the nhibernate source is the last way i think.)

Thanks.
--
Fethi Gürcan

Fethi Gürcan

unread,
Apr 10, 2009, 5:33:02 AM4/10/09
to nhusers
Hello again,

only for testing i changed the Nhibernate ActionQueue code;

it seems works. (but i'm still waiting for another legal ways. :))))  I mailed this only for sharing )

        private void ExecuteActions(IList list)
        {
            //this prevents throwing exception if collection changes.
            int actionCount = list.Count;
            for (int i = 0; i < actionCount; i++)
            {
                Execute(list[i] as IExecutable);
            }

            //if something added by the event listeners. this code execute additions
            int newActions = list.Count;
            for (int i = actionCount; i < newActions; i++)
            {
                Execute(list[i] as IExecutable);
            }

            list.Clear();
            session.Batcher.ExecuteBatch();
        }

it is works on insert operations but insert operations are first executed. (we have to make history for update,delete also)

so i've changed,

        /// <summary>
        /// Perform all currently queued actions.
        /// </summary>
        public void ExecuteActions()
        {
            ExecuteActions(insertions);
            ExecuteActions(updates);
            ExecuteActions(collectionRemovals);
            ExecuteActions(collectionUpdates);
            ExecuteActions(collectionCreations);
            ExecuteActions(deletions);

            //if something added after insert the executions.
            ExecuteActions(insertions);

        }

10 Nisan 2009 Cuma 11:58 tarihinde Fethi Gürcan <fethi...@gmail.com> yazdı:



--
Fethi Gürcan
Reply all
Reply to author
Forward
0 new messages