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