views:

152

answers:

1

I have a simple unit test where I execute the same NHibernate named query 2 times (different session each time) with the identical parameter. It's a simple int parameter, and since my query is a named query I assume these 2 calls are identical and the results should be cached.

In fact, I can see in my log that the results ARE being cached, but with different keys. So, my 2nd query results are never found in cache.

here's a snip from my log (note how the keys are different):

(first query) DEBUG NHibernate.Caches.SysCache2.SysCacheRegion [(null)] <(null)> - adding new data: key= [snipped]... parameters: ['809']; named parameters: {}@743460424 & value=System.Collections.Generic.List`1[System.Object]

(second query) DEBUG NHibernate.Caches.SysCache2.SysCacheRegion [(null)] <(null)> - adding new data: key=[snipped]... parameters: ['809']; named parameters: {}@704749285 & value=System.Collections.Generic.List`1[System.Object]

I have NHibernate set up to use the query cache. And I have these queries set to cacheable=true. Don't know where else to look. Anyone have any suggestions?

Thanks
-Mike

+2  A: 

Okay - i figured this out. I was executing my named query using the following syntax:

IQuery q = session.GetNamedQuery("MyQuery")
                .SetResultTransformer(Transformers.AliasToBean(typeof(MyDTO)))
                .SetCacheable(true)
                .SetCacheRegion("MyCacheRegion");

( which, I might add, is EXACTLY how the NHibernate docs tell you how to do it.. but I digress ;) )

If you use create a new AliasToBean Transformer for every query, then each query object (which is the key to the cache) will be unique and you will never get a cache hit. So, in short, if you do it like the nhib docs say then caching wont work.

Instead, create your transformer one time in a static member var and then use that for your query, and caching will work - like this:

private static IResultTransformer myTransformer = Transformers.AliasToBean(typeof(MyDTO))

...

IQuery q = session.GetNamedQuery("MyQuery")
                    .SetResultTransformer(myTransformer)
                    .SetCacheable(true)
                    .SetCacheRegion("MyCacheRegion");
HokieMike
The docs make no reference to transformers in the context of caching. The behavior makes sense.
Diego Mijelshon
It only makes sense once you study the logs and see what's going on. :)
HokieMike
@HokieMike nice one, came across this myself and thought was sure i'd done something wrong.
dove