Reputation: 12855
I am working on a project that requires the following:
I checked several approaches, many of them already appearing on StackOverflow. Here are my options as I see now:
Manual
In the most naive and annoying solution, I can just follow the business logic and build the query myself - E.g, if the BL builds a criteria that does a restrictions on ID=5, I'd build a query with SELECT ... WHERE ID = 5
. Since we have quite a complex BL, I'd really like to avoid that.
NHibernate interception
Originally, using the OnPrepareStatement
seemed like the best bet. However, I soon discovered that the parameters of the query aren't logged which renders it quite useless.
Introspecting NHibernarnate’s ICriteria
When performing a query with NHibernate, we do it with an ICreteria object that contains the restrictions, the sorting and the aggregations definitions. It seems I could interspect it when a CriteriaWalker that is described here. However, it seems that it gets confused on complex queries. Also, in some cases we use NHibernate 3 new "QueryOver" syntax for which this solution doesn't help me.
Using ILoggerFactory
Since NHibernate 3, you can write custom log factories (sample). This gets the full SQL, however, it also affects the whole NHibernate system and it seems it is impossible to have a factory to apply for a specific ISession, or even ISessionFactory.
Custom NHibernate driver
I've considered writing a proxy NHibernate driver and assigning it to a specific SessionFactory (as described here). However, a friendly comment warns that it longer works in Nhibernate 3.2.
Using dynamic proxies
This code uses Castle's Dynamic proxies to inject itself inside ISession. I haven't tried running it yet with my server, but I am a bit wary of using such drastic measures. If nothing else works, however, I guess it is something to consider.
Suggestions?
Right now I am a bit stuck on choosing the best way to go with since nothing seems to be doing its job, quite right. If there are other suggestions, I'd love to hear them.
Upvotes: 1
Views: 497
Reputation: 52735
I'd use a standard or custom logging framework, and apply a custom filter to retrieve a flag from thread data (for example) in order to determine whether the session should be logged.
This way, you don't mess with NH internals at all, and as long as you don't set the flag, nothing gets logged.
Upvotes: 2