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  package net.sf.ehcache.hibernate;
17  
18  
19  import net.sf.ehcache.Element;
20  import net.sf.ehcache.concurrent.CacheLockProvider;
21  import net.sf.ehcache.concurrent.LockType;
22  import net.sf.ehcache.util.Timestamper;
23  
24  import org.hibernate.cache.Cache;
25  import org.hibernate.cache.CacheException;
26  
27  import java.util.HashMap;
28  import java.util.Map;
29  
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  /***
34   * EHCache plugin for Hibernate.
35   * <p/>
36   * EHCache uses a {@link net.sf.ehcache.store.MemoryStore} and a
37   * {@link net.sf.ehcache.store.disk.DiskStore}.
38   * <p/>
39   * The {@link net.sf.ehcache.store.disk.DiskStore} requires that both keys and values be {@link java.io.Serializable}.
40   * However the MemoryStore does not and in ehcache-1.2 nonSerializable Objects are permitted. They are discarded
41   * if an attempt it made to overflow them to Disk or to replicate them to remote cache peers.
42   * <p/>
43   *
44   * @author Greg Luck
45   * @author Emmanuel Bernard
46   * @version $Id: EhCache.html 13146 2011-08-01 17:12:39Z oletizi $
47   */
48  @Deprecated
49  public final class EhCache implements Cache {
50  
51      private static final Logger LOG = LoggerFactory.getLogger(EhCache.class.getName());
52  
53      private static final int SIXTY_THOUSAND_MS = 60000;
54  
55      private final net.sf.ehcache.Ehcache cache;
56  
57      private final CacheLockProvider lockProvider;
58      
59      /***
60       * Creates a new Hibernate pluggable cache by name.
61       * <p/>
62       * ehcache will look in ehcache.xml to load the configuration for the cache.
63       * If the cache is not there, it will use the defaultCache settings. It is
64       * always a good idea to specifically configure each cache.
65       *
66       * @param cache The backing ehcache cache.
67       */
68      public EhCache(net.sf.ehcache.Ehcache cache) {
69          this.cache = cache;
70          
71          Object context = cache.getInternalContext();
72          if (context instanceof CacheLockProvider) {
73              lockProvider = (CacheLockProvider) context;
74          } else {
75              lockProvider = null;
76          }
77      }
78  
79      /***
80       * Gets a value of an element which matches the given key.
81       *
82       * @param key the key of the element to return.
83       * @return The value placed into the cache with an earlier put, or null if not found or expired
84       * @throws org.hibernate.cache.CacheException
85       *
86       */
87      public final Object get(Object key) throws CacheException {
88          try {
89                  LOG.debug("key: {}", key);
90              if (key == null) {
91                  return null;
92              } else {
93                  Element element = cache.get(key);
94                  if (element == null) {
95  
96                          LOG.debug("Element for key {} is null", key);
97                      return null;
98                  } else {
99                      return element.getObjectValue();
100                 }
101             }
102         } catch (net.sf.ehcache.CacheException e) {
103             throw new CacheException(e);
104         }
105     }
106 
107     /***
108      * Gets an object from the cache.
109      *
110      * @param key an Object value
111      * @return the Object, or null if not found
112      * @throws CacheException
113      */
114     public final Object read(Object key) throws CacheException {
115         return get(key);
116     }
117 
118 
119     /***
120      * Updates an object in the cache, or if it does not exist, inserts it.
121      *
122      * @param key   an Object key
123      * @param value an Object value
124      * @throws CacheException if the {@link net.sf.ehcache.CacheManager} is shutdown or another {@link Exception} occurs.
125      */
126     public final void update(Object key, Object value) throws CacheException {
127         put(key, value);
128     }
129 
130     /***
131      * Puts an object into the cache.
132      *
133      * @param key   an Object key
134      * @param value an Object value
135      * @throws CacheException if the {@link net.sf.ehcache.CacheManager} is shutdown or another {@link Exception} occurs.
136      */
137     public final void put(Object key, Object value) throws CacheException {
138             LOG.debug("key: {} value: {}", key, value);
139         try {
140             Element element = new Element(key, value);
141             cache.put(element);
142         } catch (IllegalArgumentException e) {
143             throw new CacheException(e);
144         } catch (IllegalStateException e) {
145             throw new CacheException(e);
146         }
147 
148     }
149 
150     /***
151      * Removes the element which matches the key.
152      * <p/>
153      * If no element matches, nothing is removed and no Exception is thrown.
154      *
155      * @param key the key of the element to remove
156      * @throws CacheException
157      */
158     public final void remove(Object key) throws CacheException {
159         try {
160             cache.remove(key);
161         } catch (ClassCastException e) {
162             throw new CacheException(e);
163         } catch (IllegalStateException e) {
164             throw new CacheException(e);
165         }
166     }
167 
168     /***
169      * Remove all elements in the cache, but leave the cache in a useable state.
170      *
171      * @throws CacheException
172      */
173     public final void clear() throws CacheException {
174         try {
175             cache.removeAll();
176         } catch (IllegalStateException e) {
177             throw new CacheException(e);
178         }
179     }
180 
181     /***
182      * Remove the cache and make it unuseable.
183      * <p/>
184      *
185      * @throws CacheException
186      */
187     public final void destroy() throws CacheException {
188         try {
189             cache.getCacheManager().removeCache(cache.getName());
190         } catch (IllegalStateException e) {
191             //When Spring and Hibernate are both involved this will happen in normal shutdown operation.
192             //Do not throw an exception, simply log this one.
193 
194                 LOG.debug("This can happen if multiple frameworks both try to shutdown ehcache", e);
195         } catch (net.sf.ehcache.CacheException e) {
196             throw new CacheException(e);
197         }
198     }
199 
200     /***
201      * {@inheritDoc}
202      */
203     public final void lock(Object key) throws CacheException {
204         if (lockProvider != null) {
205             lockProvider.getSyncForKey(key).lock(LockType.WRITE);
206         }
207     }
208 
209     /***
210      * {@inheritDoc}
211      */
212     public final void unlock(Object key) throws CacheException {
213         if (lockProvider != null) {
214             lockProvider.getSyncForKey(key).unlock(LockType.WRITE);
215         }
216     }
217 
218     /***
219      * Gets the next timestamp;
220      */
221     public final long nextTimestamp() {
222         return Timestamper.next();
223     }
224 
225     /***
226      * Returns the lock timeout for this cache, which is 60s
227      */
228     public final int getTimeout() {
229         // 60 second lock timeout
230         return Timestamper.ONE_MS * SIXTY_THOUSAND_MS;
231     }
232 
233     /***
234      * @return the region name of the cache, which is the cache name in ehcache
235      */
236     public final String getRegionName() {
237         return cache.getName();
238     }
239 
240     /***
241      * Warning: This method can be very expensive to run. Allow approximately 1 second
242      * per 1MB of entries. Running this method could create liveness problems
243      * because the object lock is held for a long period
244      * <p/>
245      *
246      * @return the approximate size of memory ehcache is using for the MemoryStore for this cache
247      */
248     public final long getSizeInMemory() {
249         try {
250             return cache.calculateInMemorySize();
251         } catch (Throwable t) {
252             return -1;
253         }
254     }
255 
256     /***
257      * @return the number of elements in ehcache's MemoryStore
258      */
259     public final long getElementCountInMemory() {
260         try {
261             return cache.getMemoryStoreSize();
262         } catch (net.sf.ehcache.CacheException ce) {
263             throw new CacheException(ce);
264         }
265     }
266 
267     /***
268      * @return the number of elements in ehcache's DiskStore. 0 is there is no DiskStore
269      */
270     public final long getElementCountOnDisk() {
271         return cache.getDiskStoreSize();
272     }
273 
274 
275     /***
276      * @return a copy of the cache Elements as a Map
277      */
278     public final Map toMap() {
279         try {
280             Map result = new HashMap();
281             for (Object key : cache.getKeys()) {
282                 Element e = cache.get(key);
283                 if (e != null) {
284                     result.put(key, e.getObjectValue());
285                 }
286             }
287             return result;
288         } catch (Exception e) {
289             throw new CacheException(e);
290         }
291     }
292 
293     /***
294      * @return <code>true</code> if this cache supports entry locks.
295      */
296     public final boolean canLockEntries() {
297         return lockProvider != null;
298     }
299 
300     /***
301      * @return the region name, which is the cache name in ehcache
302      */
303     public final String toString() {
304         return "EHCache(" + getRegionName() + ')';
305     }
306 
307     /***
308      * Package protected method used for testing
309      */
310     final net.sf.ehcache.Ehcache getBackingCache() {
311         return cache;
312     }
313 
314 }