NHibernate Fact when Saving a Transient Entity with Second Level Caching Enabled.November 23, 2008
After attending the Advanced NHibernate workshop at the Kaizen Conference, I started to do some experimenting with NHibernate in order to gather more in dept knowledge about my favorite ORM tool. A topic that quite interests me about NHibernate, is its support for caching. NHibernate currently comes with 5 different caches:
- Identity map (Session)
- Entities cache (SessionFactory)
- Collections cache (SessionFactory)
- Timestamp cache (SessionFactory)
- Query cache (SessionFactory)
The identity map is known as the first level cache, while the last four cache types in the list are all part of the second-level cache. Gabriel Schenker wrote a magnificent article on The NHibernate FAQ that provides a great overview of the different caching options available with NHibernate. There is one point that I want to add to this article that may be unclear about using the second level cache. Gabriel mentions that when a transient entity is saved to the database, NHibernate automatically puts the date of the new entity into the second level cache. This is most certainly the case, but under one condition. A transient entity is added to the second-level cache only if its identifier is not automatically generated by the underlying database. Let me show a quick example. Suppose I have an entity named User whose Id property is configured like the following:
<id name="Id" type="Int32"> <column name="Id"/> <generator class="native"/> </id>
When an new instance of User is saved in the database, NHibernate doesn’t put the data of the entity in the second level cache. When this particular entity is retrieved using a different session than the session that saved the new entity in the database, NHibernate issues a query to the DB instead of retrieving it from the second level cache.
Suppose we change the mapping of the Id property to something like this:
<id name="Id" type="Int32"> <column name="Id"/> <generator class="assigned"/> </id>
When retrieving this entity from a different session, NHibernate now reconstructs the entity from the data in the second level cache instead of sending a query to the database.
This little nuance had left me completely in the dark until I read this post on the NHibernate user group. In case of auto-generated identifiers, NHibernate doesn’t store the data of the transient entity into the second level cache because it has to hit the database anyway for retrieving the value of the corresponding identifier. Maybe this will change with NHibernate 2.1? Who knows?
I hope this clears things up.
If you and your team want to learn more about how to write maintainable unit tests and get the most out of TDD practices, make sure to have look at our trainings and workshops or check out the books section. Feel free to reach out at email@example.com.
Jan Van Ryswyck
Thank you for visiting my blog. I’m a professional software developer since Y2K. A blogger since Y2K+5. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Past organizer of the European Virtual ALT.NET meetings. Thinking and learning about all kinds of technologies since forever.
Watch The Videos
- Behavior-Driven Development
- Concurrent Programming
- Continuous Integration
- Core Skills
- Design Patterns
- Domain-Driven Design
- Event Sourcing
- Fluent Interfaces
- Functional Programming
- Object-Relational Mapping
- Open Source
- Software Design
- Test-Driven Development
- Visual Studio
The opinions expressed on this blog are my own personal opinions. These do NOT represent anyone else’s view on the world in any way whatsoever.
Thank you for visiting my website. I’m a professional software developer since Y2K. A blogger since Y2K+5. Author of Writing Maintainable Unit Tests. Provider of training and coaching in XP practices. Curator of the Awesome Talks list. Thinking and learning about all kinds of technologies since forever.