Intercepting NHibernate persistence operations on ICollection's properties (many associations)

↘锁芯ラ 提交于 2019-12-04 20:27:09

Well, I adopted a solution implementing NHibernate Listeners, so I have a listener like that:

public class CustomSaveUpdateEventListener : IPostInsertEventListener, IPostUpdateEventListener {

    private void ScheduleToCommit(AbstractPostDatabaseOperationEvent @event) {
        // Some filter
        if (@event.Entity.GetType().FullName.Equals(MY_ENTITY_TO_INTERCEPTS) {
            object o = @event.Entity;

            // Some logic...
            // ...
            // ...

            IQuery namedQuery = @event.Session.GetNamedSQLQuery(MY_NAMED_QUERY);
            //namedQuery.SetParameter(...); // <== You can set parameters
            //namedQuery.ExecuteUpdate(); // <== DO NOT EXCEUTE HERE, this launches more events recursively and can generate stackoverflow

            @event.Session.ActionQueue.RegisterProcess(new MyActionBeforeCommit(@event, namedQuery).SaveValuesOperation);
            }
        }
    }

    public void OnPostInsert(PostInsertEvent @event) {
        ScheduleToCommit(@event);
    }


    public void OnPostUpdate(PostUpdateEvent @event) {
        ScheduleToCommit(@event);
    }
}

And my object MyActionBeforeCommit() is scheduled to run only when and if a transaction is commited. So, in my "future action" I have:

public class MyActionBeforeCommit {
    private AbstractPostDatabaseOperationEvent e;

    private IQuery query;

    public MyActionBeforeCommit(AbstractPostDatabaseOperationEvent e, IQuery query) {
        this.e = e;
        this.query = query;
    }

    public void SaveValuesOperation() {
        // Here your query will be executed only when a transation is commited, if 
        // it's rolledback this won't be executed
        query.ExecuteUpdate(); 
    }
}

And finally we need to register the new listener on NHibernate configuration, like that:

Configuration.SetListener(ListenerType.PostInsert, new    CustomSaveUpdateEventListener());
Configuration.SetListener(ListenerType.PostUpdate, new CustomSaveUpdateEventListener());

And It works very well. This is a very nice NHibernate feature, very powerful.

Gert Arnold

I've waited a while to respond, because I know a possible approach, but never did it myself.

It sounds like you need to write a custom NHibernate "Dialect". There is are some guidelines here and here how to do it.

You don't mention the database system you use, but your starting point would obviously be to take the the dialect for that system and find the places where you should put your customizations.

Overriding Dialects is fully supported by NHibernate. If this does not work for you, you may even have to look at a custom AbstractEntityPersister, but I don't know how to that with configuration file entries.

You can find NHibernate 3.2 sources here.

A completely different approach could be to use standard NHibernate persistence to a local database, e.g. sql-server CE, and execute a synchronization script for the "real" persistence.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!