View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.hibernate;
18  
19  import net.sf.ehcache.AbstractCacheTest;
20  import net.sf.ehcache.CacheException;
21  import net.sf.ehcache.CacheManager;
22  import net.sf.ehcache.Ehcache;
23  import net.sf.ehcache.Element;
24  import net.sf.ehcache.util.RetryAssert;
25  import org.hamcrest.core.Is;
26  import org.hibernate.cfg.Environment;
27  import org.junit.After;
28  
29  import static java.util.concurrent.TimeUnit.SECONDS;
30  import static org.junit.Assert.assertEquals;
31  import static org.junit.Assert.assertNotNull;
32  import static org.junit.Assert.assertTrue;
33  import static org.junit.Assert.fail;
34  
35  import org.junit.Test;
36  
37  import java.io.IOException;
38  import java.io.Serializable;
39  import java.util.Map;
40  import java.util.Properties;
41  import java.util.concurrent.Callable;
42  
43  import org.slf4j.Logger;
44  import org.slf4j.LoggerFactory;
45  
46  
47  /***
48   * Tests for a Cache
49   *
50   * @author Greg Luck, Claus Ibsen
51   * @version $Id: HibernateAPIUsageTest.html 13146 2011-08-01 17:12:39Z oletizi $
52   */
53  public class HibernateAPIUsageTest extends AbstractCacheTest {
54      private static final Logger LOG = LoggerFactory.getLogger(HibernateAPIUsageTest.class.getName());
55      private static final int EMPTY_ELEMENT_SIZE = 238;
56  
57  
58      /***
59       * teardown
60       */
61      @Override
62      @After
63      public void tearDown() throws Exception {
64          super.tearDown();
65      }
66  
67  
68      /***
69       * Make sure ehcache works with one of the main projects using it: Hibernate-2.1.8
70       */
71      @Test
72      public void testAPIAsUsedByHibernate2() throws net.sf.hibernate.cache.CacheException {
73          net.sf.hibernate.cache.EhCacheProvider provider = new net.sf.hibernate.cache.EhCacheProvider();
74          provider.start(null);
75          net.sf.hibernate.cache.Cache cache = provider.buildCache("sampleCache1", null);
76          assertNotNull(manager.getCache("sampleCache1"));
77  
78          Serializable key = "key";
79          Serializable value = "value";
80          cache.put(key, value);
81          assertEquals(value, cache.get(key));
82  
83          cache.remove(key);
84          assertEquals(null, cache.get(key));
85      }
86  
87  
88      /***
89       * Make sure ehcache works with one of the main projects using it: Hibernate-3.1.3 and Hibernate 3.2
90       * Note this test was updated to Hibernate3.2cr2 9 May 2006
91       * <p/>
92       * Note that getElementCountInMemory() is broken. It reports the total cache size rather than the memory size. Fixed in Hibernate 3.2
93       * getTimeout appears to be broken. It returns 4096 minutes!
94       */
95      @Test
96      public void testAPIAsUsedByHibernate3() throws InterruptedException {
97  
98          /*Shutdown cache manager so that hibernate can start one using the same ehcache.xml disk path
99            because it does not use the singleton CacheManager any more */
100         manager.shutdown();
101 
102         org.hibernate.cache.EhCacheProvider provider = new org.hibernate.cache.EhCacheProvider();
103         provider.start(null);
104         final org.hibernate.cache.Cache cache = provider.buildCache("sampleCache1", null);
105 
106         //Check created and name
107         assertNotNull(cache.getRegionName());
108         assertEquals("sampleCache1", cache.getRegionName());
109 
110         Serializable key = "key";
111         Serializable value = "value";
112 
113         cache.put(key, value);
114         assertEquals(value, cache.get(key));
115         assertEquals(value, cache.read(key));
116 
117         cache.remove(key);
118         assertEquals(null, cache.get(key));
119 
120         //Behaves like a put
121         cache.update(key, value);
122         assertEquals(value, cache.get(key));
123         cache.remove(key);
124 
125         //Check counts and stats
126         for (int i = 0; i < 10010; i++) {
127             cache.put("" + i, value);
128         }
129         Thread.sleep(100);
130         //this is now fixed
131         assertEquals(10000, cache.getElementCountInMemory());
132         RetryAssert.assertBy(1, SECONDS, new Callable<Long>() {
133             public Long call() throws Exception {
134                 return cache.getElementCountOnDisk();
135             }
136         }, Is.is(1000L));
137 
138         //clear
139         cache.clear();
140         assertEquals(0, cache.getElementCountInMemory());
141         cache.put(key, value);
142         assertEquals(EMPTY_ELEMENT_SIZE, cache.getSizeInMemory());
143 
144         //locks
145         //timeout. This seems strange
146         assertEquals(245760000, cache.getTimeout());
147         cache.lock(key);
148         cache.unlock(key);
149 
150         //toMap
151         Map map = cache.toMap();
152         assertEquals(1, map.size());
153         assertEquals(value, map.get(key));
154 
155         long time1 = cache.nextTimestamp();
156         long time2 = cache.nextTimestamp();
157         assertTrue(time2 > time1);
158 
159         cache.clear();
160 
161         cache.destroy();
162         try {
163             cache.get(key);
164             fail();
165         } catch (IllegalStateException e) {
166             //expected
167         }
168 
169         provider.stop();
170 
171     }
172 
173 
174     /***
175      * Test new features:
176      * <ol>
177      * <li>Support for Object signatures
178      * <li>support for multiple SessionFactory objects in Hibernate, which presumably mean multiple providers.
179      * We can have two caches of the same name in different providers and interact with both
180      * </ol>
181      */
182     @Test
183     public void testNewHibernate32CacheAndProviderNewFeatures() {
184 
185         /*Shutdown cache manager so that hibernate can start one using the same cache.xml disk path
186           because it does not use the singleton CacheManager any more */
187         manager.shutdown();
188 
189         org.hibernate.cache.EhCacheProvider provider = new org.hibernate.cache.EhCacheProvider();
190         provider.start(null);
191         org.hibernate.cache.Cache cache = provider.buildCache("sampleCache1", null);
192 
193         //start up second provider pointing to ehcache-failsage.xml because it is there
194         org.hibernate.cache.EhCacheProvider provider2 = new org.hibernate.cache.EhCacheProvider();
195 
196         //Fire up a second provider, CacheManager and cache concurrently
197         Properties properties = new Properties();
198 
199         properties.setProperty(Environment.CACHE_PROVIDER_CONFIG, "ehcache-2.xml");
200         provider2.start(properties);
201         org.hibernate.cache.Cache cache2 = provider.buildCache("sampleCache1", null);
202 
203         //Check created and name
204         assertNotNull(cache.getRegionName());
205         assertEquals("sampleCache1", cache.getRegionName());
206 
207         //Test with Object rather than Serializable
208         Object key = new Object();
209         Object value = new Object();
210 
211         cache.put(key, value);
212         assertEquals(value, cache.get(key));
213         assertEquals(value, cache.read(key));
214         cache2.put(key, value);
215         assertEquals(value, cache2.get(key));
216         assertEquals(value, cache2.read(key));
217 
218         cache.remove(key);
219         assertEquals(null, cache.get(key));
220         cache2.remove(key);
221         assertEquals(null, cache2.get(key));
222 
223         //Behaves like a put
224         cache.update(key, value);
225         assertEquals(value, cache.get(key));
226         cache.remove(key);
227         cache2.update(key, value);
228         assertEquals(value, cache2.get(key));
229         cache2.remove(key);
230 
231         //Check counts and stats
232         for (int i = 0; i < 10010; i++) {
233             cache.put("" + i, value);
234         }
235         assertEquals(10000, cache.getElementCountInMemory());
236         //objects don't overflow, only Serializable
237         assertEquals(0, cache.getElementCountOnDisk());
238 
239         //clear
240         cache.clear();
241         assertEquals(0, cache.getElementCountInMemory());
242         cache.put(key, value);
243         //Not Serializable therefore unmeasurable using ehcache's estimation algorithm
244         assertTrue(0 == cache.getSizeInMemory());
245 
246         //locks
247         //timeout. This seems strange
248         assertEquals(245760000, cache.getTimeout());
249         cache.lock(key);
250         cache.unlock(key);
251 
252         //toMap - broken in Hibernate 3.2
253 //        Map map = cache.toMap();
254 //        assertEquals(1, map.size());
255 //        assertEquals(value, map.get(key));
256 
257         long time1 = cache.nextTimestamp();
258         long time2 = cache.nextTimestamp();
259         assertTrue(time2 > time1);
260 
261         cache.destroy();
262         try {
263             cache.get(key);
264             fail();
265         } catch (IllegalStateException e) {
266             //expected
267         }
268 
269         cache2.destroy();
270         try {
271             cache2.get(key);
272             fail();
273         } catch (IllegalStateException e) {
274             //expected
275         }
276 
277         provider.stop();
278         provider2.stop();
279     }
280 
281 
282     /***
283      * Test ehcache packaged provider and EhCache with Hibernate-3.1.3
284      * Leave broken timeout until get clarification from Emmanuel
285      */
286     @Test
287     public void testNewHibernateEhcacheAndProviderBackwardCompatible() {
288 
289         /*Shutdown cache manager so that hibernate can start one using the same cache.xml disk path
290           because it does not use the singleton CacheManager any more */
291         manager.shutdown();
292 
293         net.sf.ehcache.hibernate.EhCacheProvider provider = new net.sf.ehcache.hibernate.EhCacheProvider();
294 
295         //Fire up a second provider, CacheManager and cache concurrently
296         Properties properties = new Properties();
297 
298         properties.setProperty("net.sf.ehcache.configurationResourceName", "ehcache-2.xml");
299         provider.start(properties);
300         final org.hibernate.cache.Cache cache = provider.buildCache("sampleCache1", null);
301 
302         //Check created and name
303         assertNotNull(cache.getRegionName());
304         assertEquals("sampleCache1", cache.getRegionName());
305 
306         Serializable key = "key";
307         Serializable value = "value";
308 
309         cache.put(key, value);
310         assertEquals(value, cache.get(key));
311         assertEquals(value, cache.read(key));
312 
313         cache.remove(key);
314         assertEquals(null, cache.get(key));
315 
316         //Behaves like a put
317         cache.update(key, value);
318         assertEquals(value, cache.get(key));
319         cache.remove(key);
320 
321         //Check counts and stats
322         for (int i = 0; i < 10010; i++) {
323             cache.put("" + i, value);
324         }
325         assertEquals(10000, cache.getElementCountInMemory());
326         RetryAssert.assertBy(2, SECONDS, new Callable<Long>() {
327                 public Long call() throws Exception {
328                     return cache.getElementCountOnDisk();
329                 }
330             }, Is.is(10010L));
331 
332         //clear
333         cache.clear();
334         assertEquals(0, cache.getElementCountInMemory());
335         cache.put(key, value);
336         assertTrue(EMPTY_ELEMENT_SIZE == cache.getSizeInMemory());
337 
338         //locks
339         //timeout. This seems strange
340         assertEquals(245760000, cache.getTimeout());
341         cache.lock(key);
342         cache.unlock(key);
343 
344         //toMap
345         Map map = cache.toMap();
346         assertEquals(1, map.size());
347         assertEquals(value, map.get(key));
348 
349         long time1 = cache.nextTimestamp();
350         long time2 = cache.nextTimestamp();
351         assertTrue(time2 > time1);
352 
353         cache.destroy();
354         try {
355             cache.get(key);
356             fail();
357         } catch (IllegalStateException e) {
358             //expected
359         }
360 
361         ((net.sf.ehcache.hibernate.EhCache) cache).getBackingCache().getCacheManager().shutdown();
362 
363 
364     }
365 
366 
367     /***
368      * An integration test, at the CacheManager level, to make sure persistence works
369      */
370     @Test
371     public void testPersistentStoreFromCacheManager() throws IOException, InterruptedException, CacheException {
372 
373         manager.shutdown();
374 
375         //initialise
376         CacheManager manager = CacheManager.create(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache.xml");
377         Ehcache cache = manager.getCache("persistentLongExpiryIntervalCache");
378 
379         for (int i = 0; i < 100; i++) {
380             byte[] data = new byte[1024];
381             cache.put(new Element("key" + (i + 100), data));
382         }
383         assertEquals(100, cache.getSize());
384 
385         manager.shutdown();
386 
387         net.sf.ehcache.hibernate.EhCacheProvider provider = new net.sf.ehcache.hibernate.EhCacheProvider();
388         provider.start(null);
389         org.hibernate.cache.Cache hibernateCache = provider.buildCache("persistentLongExpiryIntervalCache", null);
390 
391         assertEquals(100, hibernateCache.getElementCountInMemory() + hibernateCache.getElementCountOnDisk());
392 
393         provider.stop();
394 
395 
396     }
397 
398 
399     /***
400      * An integration test, at the CacheManager level, to make sure persistence works
401      */
402     @Test
403     public void testPersistentStoreFromCacheManagerUsingHibernate321Provider() throws Exception {
404 
405         manager.shutdown();
406 
407         //initialise
408         CacheManager manager = CacheManager.create(AbstractCacheTest.TEST_CONFIG_DIR + "ehcache.xml");
409         Ehcache cache = manager.getCache("persistentLongExpiryIntervalCache");
410         cache.removeAll();
411 
412         for (int i = 0; i < 100; i++) {
413             byte[] data = new byte[1024];
414             cache.put(new Element("key" + (i + 100), data));
415         }
416         assertEquals(100, cache.getSize());
417 
418         manager.shutdown();
419 
420         //Create hibernate using ehcache
421         org.hibernate.cache.EhCacheProvider provider = new org.hibernate.cache.EhCacheProvider();
422         provider.start(null);
423         org.hibernate.cache.Cache hibernateCache = provider.buildCache("persistentLongExpiryIntervalCache", null);
424 
425         assertEquals(100, hibernateCache.getElementCountInMemory() + hibernateCache.getElementCountOnDisk());
426 
427         provider.stop();
428 
429     }
430 
431     /***
432      * Test ehcache packaged provider and EhCache with Hibernate-3.1.3
433      * Leave broken timeout until get clarification from Emmanuel
434      * <p/>
435      * Test new features:
436      * <ol>
437      * <li>Support for Object signatures
438      * <li>support for multiple SessionFactory objects in Hibernate, which presumably mean multiple providers.
439      * We can have two caches of the same name in different providers and interact with both
440      * </ol>
441      */
442     @Test
443     public void testNewHibernateEhcacheAndProviderNewFeatures() {
444 
445         /*Shutdown cache manager so that hibernate can start one using the same ehcache.xml disk path
446           because it does not use the singleton CacheManager any more */
447         manager.shutdown();
448 
449         net.sf.ehcache.hibernate.EhCacheProvider provider = new net.sf.ehcache.hibernate.EhCacheProvider();
450         provider.start(null);
451         org.hibernate.cache.Cache cache = provider.buildCache("sampleCache1", null);
452 
453         //start up second provider pointing to ehcache-failsafe.xml because it is there
454         net.sf.ehcache.hibernate.EhCacheProvider provider2 = new net.sf.ehcache.hibernate.EhCacheProvider();
455 
456         //Fire up a second provider, CacheManager and cache concurrently
457         Properties properties = new Properties();
458         properties.setProperty(EhCacheProvider.NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME, "ehcache-2.xml");
459         provider2.start(properties);
460         org.hibernate.cache.Cache cache2 = provider.buildCache("sampleCache1", null);
461 
462         //Check created and name
463         assertNotNull(cache.getRegionName());
464         assertEquals("sampleCache1", cache.getRegionName());
465 
466         //Test with Object rather than Serializable
467         Object key = new Object();
468         Object value = new Object();
469 
470         cache.put(key, value);
471         assertEquals(value, cache.get(key));
472         assertEquals(value, cache.read(key));
473         cache2.put(key, value);
474         assertEquals(value, cache2.get(key));
475         assertEquals(value, cache2.read(key));
476 
477         cache.remove(key);
478         assertEquals(null, cache.get(key));
479         cache2.remove(key);
480         assertEquals(null, cache2.get(key));
481 
482         //Behaves like a put
483         cache.update(key, value);
484         assertEquals(value, cache.get(key));
485         cache.remove(key);
486         cache2.update(key, value);
487         assertEquals(value, cache2.get(key));
488         cache2.remove(key);
489 
490         //Check counts and stats
491         for (int i = 0; i < 10010; i++) {
492             cache.put("" + i, value);
493         }
494         assertEquals(10000, cache.getElementCountInMemory());
495         //objects don't overflow, only Serializable
496         assertEquals(0, cache.getElementCountOnDisk());
497 
498         //clear
499         cache.clear();
500         assertEquals(0, cache.getElementCountInMemory());
501         cache.put(key, value);
502         //Not Serializable therefore unmeasurable using ehcache's estimation algorithm
503         assertTrue(0 == cache.getSizeInMemory());
504 
505         //locks
506         //timeout. This seems strange
507         assertEquals(245760000, cache.getTimeout());
508         cache.lock(key);
509         cache.unlock(key);
510 
511         //toMap
512         Map map = cache.toMap();
513         assertEquals(1, map.size());
514         assertEquals(value, map.get(key));
515 
516         long time1 = cache.nextTimestamp();
517         long time2 = cache.nextTimestamp();
518         assertTrue(time2 > time1);
519 
520         cache.destroy();
521         try {
522             cache.get(key);
523             fail();
524         } catch (IllegalStateException e) {
525             //expected
526         }
527 
528         cache2.destroy();
529         try {
530             cache2.get(key);
531             fail();
532         } catch (IllegalStateException e) {
533             //expected
534         }
535 
536         ((net.sf.ehcache.hibernate.EhCache) cache).getBackingCache().getCacheManager().shutdown();
537     }
538 
539     /***
540      * Test ehcache packaged provider and EhCache with Hibernate-3.1.3
541      * Leave broken timeout until get clarification from Emmanuel
542      * <p/>
543      * Test new features:
544      * <ol>
545      * <li>Support for Object signatures
546      * </ol>
547      */
548     @Test
549     public void testNewHibernateSingletonEhcacheAndProviderNewFeatures() {
550 
551         /*Shutdown cache manager so that hibernate can start one using the same ehcache.xml disk path
552           because it does not use the singleton CacheManager any more */
553         manager.shutdown();
554 
555         net.sf.ehcache.hibernate.SingletonEhCacheProvider provider = new net.sf.ehcache.hibernate.SingletonEhCacheProvider();
556         provider.start(null);
557         org.hibernate.cache.Cache cache = provider.buildCache("sampleCache1", null);
558 
559         net.sf.ehcache.hibernate.SingletonEhCacheProvider provider2 = new net.sf.ehcache.hibernate.SingletonEhCacheProvider();
560         provider2.start(null);
561         org.hibernate.cache.Cache cache2 = provider.buildCache("sampleCache1", null);
562 
563         //Check created and name
564         assertNotNull(cache.getRegionName());
565         assertEquals("sampleCache1", cache.getRegionName());
566 
567         //Test with Object rather than Serializable
568         Object key = new Object();
569         Object value = new Object();
570 
571         cache.put(key, value);
572         assertEquals(value, cache2.get(key));
573         assertEquals(value, cache.read(key));
574         cache2.put(key, value);
575         assertEquals(value, cache.get(key));
576         assertEquals(value, cache2.read(key));
577 
578         cache.remove(key);
579         assertEquals(null, cache.get(key));
580         cache2.remove(key);
581         assertEquals(null, cache2.get(key));
582 
583         //Behaves like a put
584         cache.update(key, value);
585         assertEquals(value, cache.get(key));
586         cache.remove(key);
587         cache2.update(key, value);
588         assertEquals(value, cache2.get(key));
589         cache2.remove(key);
590 
591         //Check counts and stats
592         for (int i = 0; i < 10010; i++) {
593             cache.put("" + i, value);
594         }
595         assertEquals(10000, cache.getElementCountInMemory());
596         //objects don't overflow, only Serializable
597         assertEquals(0, cache.getElementCountOnDisk());
598 
599         //clear
600         cache.clear();
601         assertEquals(0, cache.getElementCountInMemory());
602         cache.put(key, value);
603         //Not Serializable therefore unmeasurable using ehcache's estimation algorithm
604         assertTrue(0 == cache.getSizeInMemory());
605 
606         //locks
607         //timeout. This seems strange
608         assertEquals(245760000, cache.getTimeout());
609         cache.lock(key);
610         cache.unlock(key);
611 
612         //toMap
613         Map map = cache.toMap();
614         assertEquals(1, map.size());
615         assertEquals(value, map.get(key));
616 
617         long time1 = cache.nextTimestamp();
618         long time2 = cache.nextTimestamp();
619         assertTrue(time2 > time1);
620 
621         cache.destroy();
622         try {
623             cache.get(key);
624             fail();
625         } catch (IllegalStateException e) {
626             //expected
627         }
628 
629         cache2.destroy();
630         //second destroy ok
631         cache2.destroy();
632 
633         try {
634             cache2.get(key);
635             fail();
636         } catch (IllegalStateException e) {
637             //expected
638         }
639 
640 
641         ((net.sf.ehcache.hibernate.EhCache) cache).getBackingCache().getCacheManager().shutdown();
642         ((net.sf.ehcache.hibernate.EhCache) cache).getBackingCache().getCacheManager().shutdown();
643         ((net.sf.ehcache.hibernate.EhCache) cache2).getBackingCache().getCacheManager().shutdown();
644 
645         //Spring and Hibernate together can call destroy after the CacheManager has been shutdown
646         //See bug 1901094. We need to deal with this as "normal".
647         cache2.destroy();
648     }
649 }