As some of you know I am attending KaizenConf for the next few days. I am going to use my blog as my notepad as I take notes during different workshops and sessions. My note taking skills sometimes have a lot to be desired so be patient if these notes look very sketchy. I will try my best to come back through and make sense of them later.
Advanced NHibernate
I am currently sitting through Ayende’s workshop on Advanced NHibernate and there is some really good stuff going on here. Three of the topics I have found most interesting is Multi-Tenancy, Full text indexing with NHibernate Search, and caching with NHibernate. NHibernate search is a project that combines Lucene, a proven java index tool, and NHibernate to alleviate strain on the database engine by keeping indexes on disk and performing queries on that data faster. Indexing is accomplished by decorating entities with attributes. Of all these topics caching with NHibernate has really grabbed my attention as it probably has the greatest results for the applications I am currently working.
Caching with NHibernate
1st Level cache –Contains Identity Map – Session – Single instance of an object in a particular session
2nd Level Cache – contains the SessionFactory – lives for the entire application lifetime, it also has 4 levels of cache within it:
timestamp
query cache
collection cache
entity cache
Caching Configuration
Enable query cache <property name=”cache.use_second_level_cache”>True</property> in NHConfig – A single on off switch in the application to enable/disable caching is not a good solution because caching is complex and could affect business rules and performance. So you have to enable caching for a specific entity by using Cache_usage = CacheMode (ReadWrite for Ayende’s samples) in the entity mapping file. The NHibernate cache hashtables are stored like below:
Entities Cache:
————————-
Blog#1 : { Name: “…”}
Post#1 : {…}
Post#2 {…}
Collection Cache
—————————
Blog#1.Posts { 1,2,3,4,5,6} – stores id’s only
Query Cache:
—————————
“select top 5 * from Post” : {1,2,3,4} // stores id’s only
Ayende used his blog sample for all of the code examples today. When he put caching on the Blog, and the collection of posts in the blog map and on the post entity the fewest calls to the database occurred. To enable query caching the property cache.use_query_cache = true in the config file.
Session.Load vs Session.Get
Load == I know the entity exists in the database, it returns a proxy to the object. Throws an exception if the object is not lazy loaded and cannot be found.
Get == NH really goes to the database and fetches a row or throws an exception if it does not exist.
Which one of these to use depends on the business rule for the entity.
NHibernate cache libraries:
PrevelanceCache – persistent caching for smart client applications
SysCache – using ASP.net caching – gives it the ability to put things in the cache and forget about it – only works if you have one machine. Other wise you get cache poisoning.
SysCache2 – ASP.net caching in the farm – maybe application is not the only thing that updates the database. This is good when the application is not the sole owner of the database.
MemCache – a distributed hashtable, thats it basically it is distributed caching.– Server sitting on TCP with a hashtable – the Client caches the key and always goes back to same server in farm for cache retrieval. Very simple, works very well. This is also known as MemCacheD and is the same caching strategy that Facebook uses.
SharedCache – SharedCache from CodePlex
Velocity – From Microsoft – more complex than memcache, more options but they validate the cache space you have.
Other NHibernate Contrib Projects
NHibernate.Linq – pretty good, handles most of the common scenarios, does not handle the crazy scenarios that are capable in LINQ. Currently working on a fully functional LINQ library.
NHibernate.Validator– Just as you can specify constraints in SQL Server. You can specify constraints in your mapping file and the validator will validate that for you.
Spatial – GIS applications
Shards – partition the data across multiple db’s – written by Google to deal with problem of having multiple database. You can teach NHibernate a sharding strategy so that it knows which database to use. This is a strategy that is used by companies such as Facebook.
Another very interesting topic Ayende talked about is self optimizing queries. This would be used by session.Future<TYPE>() you could use this in your repositories on all lists/CreateCriteria methods. This creates a MultiCriteria which returns multiple result sets in one database trip. This is very similar/exactly like multiple result sets in stored procedures.
Tags: .NET (C#), alt.net, Development, KaizenConf, NHibernate