[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-1813) 2nd level cached collections are locked causing a cache miss

Erik Heckert (JIRA) noreply at atlassian.com
Sat Sep 30 09:09:26 EDT 2006


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-1813?page=comments#action_24686 ] 

Erik Heckert commented on HHH-1813:
-----------------------------------

Hi Assaf. Of course you are perfectly right.
I've made some code investigation, and now I believe I have an idea of what goes wrong.

org.hibernate.cache.ReadWriteCache has an internal class "Item". In Item's methode "isGettable"
"freshTimestamp" and "txTimestamp" are compared.
"freshTimestamp" is the point in time the item has been put into the cache.
"txTimestamp" should be the point in time the transaction has begun.
What a pity: "txTimestamp" is not only always < "freshTimestamp", it never changes!

Have a look at "org.hibernate.event.def.DefaultLoadEventListener.loadFromSecondLevelCache (...)".
Here the get-method of ReadWriteCache is called, and "txTimestamp" is the timestamp of the
session, not the transaction!

So, if you use session pooling (I do), ReadWriteCache will always fail for you, because txTimestamp
does not advance.
I think the transaction should have a timestamp which should be filled into the get method, but for
the time being we need a work around:

Simply do not pool your sessions, close them after the commit or rollback. This way your cache works.
It does for me now.

What do you think?

> 2nd level cached collections are locked causing a cache miss
> ------------------------------------------------------------
>
>          Key: HHH-1813
>          URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-1813
>      Project: Hibernate3
>         Type: Bug

>     Versions: 3.1
>  Environment: Hibernate 3.1, Oracle 10g, Linux
>     Reporter: Assaf Berg
>     Priority: Critical
>  Attachments: testcase.tar.gz
>
>
> Using the second level cache, collections are fetched from the database due to the cached item being locked.
> This happens in the most simple use case:
> 1. Insert an entity with a collection
> 2. Commit. 
> 3. Fetch the entity
> I've written a simple test case and see the following in the log file:
> 11:52:47,159 DEBUG [ReadWriteCache] Invalidating: domain.Cat.kittens#539957
> 11:52:47,177 DEBUG [ReadWriteCache] Inserting: domain.Cat#539957
> 11:52:47,179 DEBUG [ReadWriteCache] Inserted: domain.Cat#539957
> 11:52:47,180 DEBUG [ReadWriteCache] Inserting: domain.Kitten#540214
> 11:52:47,180 DEBUG [ReadWriteCache] Inserted: domain.Kitten#540214
> 11:52:47,181 DEBUG [ReadWriteCache] Releasing: domain.Cat.kittens#539957
> 11:52:49,221 DEBUG [ReadWriteCache] Caching: domain.Cat#539957
> 11:52:49,221 DEBUG [ReadWriteCache] Item was already cached: domain.Cat#539957
> 11:52:49,223 DEBUG [ReadWriteCache] Cache lookup: domain.Cat.kittens#539957
> 11:52:49,223 DEBUG [ReadWriteCache] Cached item was locked: domain.Cat.kittens#539957
> 11:52:49,229 DEBUG [ReadWriteCache] Caching: domain.Kitten#540214
> 11:52:49,229 DEBUG [ReadWriteCache] Item was already cached: domain.Kitten#540214
> 11:52:49,230 DEBUG [ReadWriteCache] Caching: domain.Cat.kittens#539957
> 11:52:49,231 DEBUG [ReadWriteCache] Cached: domain.Cat.kittens#539957
> domain.Cat.kittens [C/H/M/P]: 1/0/1/1
> domain.Cat [C/H/M/P]: 1/0/0/1
> domain.Kitten [C/H/M/P]: 1/0/0/1
> This happens whether the collection is mapped as inverse or not.
> I've attached the test case source and hbms (although it might need to be tweaked for the proper DB before running, and I didn't include the dependencies JARs).
> Here's a code excerpt of the interesting part (tx is TransactionTemplate using HibnerateTransactionManager and hibernate is HibernateTemplate from the spring framework):
> 		tx.execute(new TransactionCallback() {
> 			public Object doInTransaction(TransactionStatus status) {
> 				// create a Cat with one Kitten
> 				Cat cat = new Cat();
> 				Kitten kitten = new Kitten();
> 				cat.addKitten(kitten);
> 				
> 				hibernate.save(cat);
> 				
> 				return null;
> 			}			
> 		});
> 		
> 		Thread.sleep(2000L);
> 		
> 		tx.execute(new TransactionCallback() {
> 			public Object doInTransaction(TransactionStatus status) {
> 				// load all cats
> 				List<Cat> allCats = hibernate.loadAll(Cat.class);
> 				return null;
> 			}
> 		});
> I can supply further information if needed.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira




More information about the hibernate-issues mailing list