views:

38

answers:

1

Under one UnitOfWork (session) I may call CreateCriteria twice. My first call is to populate a grid for data editing. Let's say the data has been edited and flushed (saved) to the database and the grid is still open. After the data is edited, I may call CreateCriteria a second time to retrieve a list of objects that are validated and found in error.

Lets say ObjectA was retrieved by both calls to session.CreateCriteria. It was edited in the grid but found in error within the second list.

The first question would be: Considering first level cache, is ObjectA--that was retrieved from the second call to CreateCriteri--represent the one retrieved from the first call? or, better yet, did NHibernate "detect and reuse" ObjectA from the first call assuming the keys did not change?

To my final point in question: I want to edit ObjectA which was found in error, and let's say it was brought up in a ListBox. Therefore, I want to highlight that object, call session.Get()(key) in order to retrieve it from cache, then bring up a change form to change ObjectA's properties. Which object am I changing? The one from the first call to CreateCriteria or the second call? Are they the same?

Thank you in advance.

A: 

Second level cache

Take a look at http://ayende.com/Blog/archive/2006/07/24/DeepDivingIntoNHibernateTheSecondLevelCache.aspx and http://www.javalobby.org/java/forums/t48846.html

From the former:

The second level cache does not hold entities, but collections of values

So, with caching setup properly, NHibernate will be able to recreate your object without having to get the actual values from the database. In other words, the object will be created the same as when it wasn't in cache, except that since the values are cached, NHibernate won't actually query the database since it already knows what's in there.

I'm not quite sure what you mean by "validation" and "found in error". Are you validating before insert? Typically my entities are validated before the insert/update and won't actually be inserted/updated if invalid.

Validation aside, what I think you're asking is that if you:

  1. save something
  2. do a flush
  3. retrieve an item (from a new session) with the same key as the one saved in step 1

will you be retrieving the same reference to the object you saved in step 1(?). And the answer is no since NHibernate does not cache the OBJECT but rather the values so it can create a new entity populated with the cached values (instead of actually performing a DB query).

However, does that really matter? If you overload Equals such that equality of 2 entities are based on their ID, then finding the same (not reference equal, but same) item in a grid (or a hash of any kind) should be a snap.


First level cache

I didn't realize you were talking about 1st level cache. 1st level cache works as an identity map and does cache the instance of the object. Therefore, if you do 2 selects from the db based on the same ID, you will retrieve the same instance of the object.

statichippo
Brian
Also, I do implement equals, so based on your answer, I'm assuming that the Get operation looks at that method to compare objects within the cache. That being said, wouldn't the CreateCriteria, after getting the list of objects a second time, compare those objects to the cache? If so, what happens if a value has changed since the first time it was pulled from the database using CreateCriteria?
Brian
I'm sorry, I assumed you were talking about 2nd level cache (retrieving object outside scope of original retrieval session) since this is a question a lot of people have about 2nd level cache. If you're referring to 1st level cache, then yes, they will be the same instance and be have reference equality.
statichippo