[hibernate-issues] [Hibernate-JIRA] Assigned: (HHH-5945) Race condition in building query cache
Strong Liu (JIRA)
noreply at atlassian.com
Thu Nov 17 15:17:19 EST 2011
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-5945?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Strong Liu reassigned HHH-5945:
-------------------------------
Assignee: Strong Liu
> Race condition in building query cache
> --------------------------------------
>
> Key: HHH-5945
> URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5945
> Project: Hibernate Core
> Issue Type: Bug
> Components: caching (L2)
> Affects Versions: 3.6.1
> Environment: Hibernate 3.6.1, EhCache 2.3.0..2.3.2, MSSQL 2005 Developer Edition
> Reporter: Luca Domenichini
> Assignee: Strong Liu
> Attachments: TestCase.zip
>
> Original Estimate: 1h
> Remaining Estimate: 1h
>
> I have this sample program that creates 10 threads that executes the same cached query in a thread-local current session context. Entity ClasseAltezza is a READ_ONLY cached entity.
> {panel}{noformat}
> public static void main(String[] args) {
> List<Thread> threads = new ArrayList<Thread>();
> for (int i=0; i<10; i++) {
> Thread t = new Thread() {
> @Override
> public void run() {
> try {
> HibernateUtil.beginTransaction();
> HibernateUtil.getCurrentSession()
> .createCriteria(ClasseAltezza.class)
> .setCacheable(true)
> .setCacheRegion(ClasseAltezza.class.toString())
> .list();
> HibernateUtil.commitTransaction();
> }
> catch (Exception ex) {
> ex.printStackTrace();
> HibernateUtil.rollbackTransaction();
> }
> }
> };
> threads.add(t);
> }
> for (Thread t : threads)
> t.start();
> }
> {noformat}{panel}
> This is the output:
> {panel}{noformat}org.hibernate.cache.CacheException: net.sf.ehcache.ObjectExistsException: Cache class com.promag.wms.base.persistence.entities.ClasseAltezza already exists
> at org.hibernate.cache.EhCacheProvider.buildCache(EhCacheProvider.java:101)
> at org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge.buildQueryResultsRegion(RegionFactoryCacheProviderBridge.java:115)
> at org.hibernate.cache.StandardQueryCache.<init>(StandardQueryCache.java:78)
> at org.hibernate.cache.StandardQueryCacheFactory.getQueryCache(StandardQueryCacheFactory.java:44)
> at org.hibernate.impl.SessionFactoryImpl.getQueryCache(SessionFactoryImpl.java:1173)
> at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2285)
> at org.hibernate.loader.Loader.list(Loader.java:2268)
> at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
> at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
> at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
> at com.promag.wms.base.persistence.methods.ClasseAltezzaMethods.getAll(ClasseAltezzaMethods.java:30)
> at Test$1.run(Test.java:20)
> Caused by: net.sf.ehcache.ObjectExistsException: Cache class com.promag.wms.base.persistence.entities.ClasseAltezza already exists
> at net.sf.ehcache.CacheManager.addCache(CacheManager.java:888)
> at org.hibernate.cache.EhCacheProvider.buildCache(EhCacheProvider.java:94)
> ... 11 more
> {noformat}{panel}
> I see that in Hibernate 3.6.0 there were a synchronized block in method SessionFactory.getQueryCache(String regionName) the prevented the same query region to be built twice as it happens in Hibernate 3.6.1, were the synchronized block is missing..
> This is the method in SessionFactoryImpl:
> {panel}{noformat}
> public QueryCache getQueryCache(String regionName) throws HibernateException {
> if ( regionName == null ) {
> return getQueryCache();
> }
> if ( !settings.isQueryCacheEnabled() ) {
> return null;
> }
> synchronized ( allCacheRegions ) { // THIS SYNCHRONIZED IS MISSING IN 3.6.1!!!!
> QueryCache currentQueryCache = ( QueryCache ) queryCaches.get( regionName );
> if ( currentQueryCache == null ) {
> currentQueryCache = settings.getQueryCacheFactory().getQueryCache( regionName, updateTimestampsCache, settings, properties );
> queryCaches.put( regionName, currentQueryCache );
> allCacheRegions.put( currentQueryCache.getRegion().getName(), currentQueryCache.getRegion() );
> }
> return currentQueryCache;
> }
> }
> {noformat}{panel}
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the hibernate-issues
mailing list