NHibernate cache system. Part 1
In this series of articles I will try to explain you how NHibernate cache system works and how it should be used in order to get the best performance/configuration from this product.
- Introduction
- Architecture
- Cache Level 1 mechanism
- Load and Get, what’s the difference
- Session maintenance: Evict, Flush and Clear
- 2nd Level Cache
- Architecture
- Configuration
- Cache by mapping
- Cache by query
- Final advice
- Cache providers (most known)
NHibernate Cache architecture
NHibernate has an internal cache architecture that I will define absolutely well done. On an architectural point of view, it is designed for the enterprise and it is 100% configurable. Consider that it allows you to create also your custom cache provider!
The following picture show the cache architecture overview of NHibernate (actually the version I am talking about is the 3.2 GA).
The cache system is composed by two levels, the cache of level 1 that usually it is configured by default if you are working with the ISession object, and the cache of level 2 that by default is disabled.
The cache of level 1 is provided by the ISession data context and it is maintained by the lifecycle of the ISession object, this means that as soon as you destroy (dispose) an ISession object, also the cache of level 1 will be destroyed and all the corresponding objects will be detached from the ISession. This cache system works on a per transaction basis and it is designed to reduce the number of database calls during the lifecycle of an ISession. As an example, you should use this cache if you have the need to access and modify an object in a transaction, multiple times.
The cache of level 2 is provided by the ISessionFactory component and it is shared across all the session created using the same factory. Its lifecycle correspond to the lifecycle of the session factory and it provides a more powerful but also dangerous set of features. It allows you to keep objects in cache across multiple transactions and sessions; the objects are available everywhere and not only on the client that is using a specific ISession.
Cache Level 1 mechanism
As soon as you start to create a new ISession (not an IStatelessSession!!) NHibernate starts to holds in memory, using a specific mechanism, all the objects that are involved with the current session. The methods used by NHibernate to load the data into the cache are two: **Get
Another way to put an object into the lvl1 cache is to use persistence methods like Save, Delete, Update and SaveOrUpdate.
As you can see from the previous picture, the ISession object is able to contains two different categories of entities, the one that we define “loaded” using Get or Load and the one that we define “dirty”, which means that they were somehow modified and associated with a session.
Load and Get, what’s the difference?
A major confusion I personally noticed while working with NHibernate is the not correct usage of the two methods Get and Load so let’s see for a moment how they work and when they should or should not be used.
</td> |
Get |
</td> |
Load |
</tr> | |||||||||||||||||||||
Fetch method |
Retrieve the entire entity in one SELECT statement and puts the entity in the cache. |
</td> |
Retrieve only the ID of the entity and returns a non fetched proxy instance of the entity. As soon as you “hit” a property, the entity is loaded. |
</td> </tr> | |||||||||||||||||||||
How it loads |
It verifies if the entity is in the cache, otherwise it tries to execute a SELECT |
</td> |
It verifies if the entity is in the cache, otherwise it tries to execute a SELECT |
</td> </tr> | |||||||||||||||||||||
Not Available |
If the entity does not exist, it returns NULL |
</td> |
If the entity does not exist, it THROW an exception |
</td> </tr> | |||||||||||||||||||||
</td> |
</td> |
</td> |
</td> | </tr> </tbody> </table> |
Session.Clear |
Session.Evict |
Session.Flush |
||||
Removed all the existing objects from the ISession without syncing them with the database |
</td> |
Remove a specific object from the ISession without syncing it with the database |
</td> |
Remove all the existing objects from the session by syncing them with the database |
</td> </tr> </tbody> </table> I will probably write more about these three methods in some future post but if you need to investigate more about them, I would suggest you to read carefully the NHibernate docs available here: http://www.nhforge.org/doc/nh/en/index.html In the next article we talk about the level 2 cache. |