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  import java.net.URL;
19  import java.util.Properties;
20  
21  import net.sf.ehcache.CacheManager;
22  import net.sf.ehcache.Ehcache;
23  import net.sf.ehcache.hibernate.management.impl.ProviderMBeanRegistrationHelper;
24  import net.sf.ehcache.hibernate.nonstop.NonstopAccessStrategyFactory;
25  import net.sf.ehcache.hibernate.regions.EhcacheQueryResultsRegion;
26  import net.sf.ehcache.hibernate.regions.EhcacheTimestampsRegion;
27  import net.sf.ehcache.hibernate.regions.EhcacheEntityRegion;
28  import net.sf.ehcache.hibernate.regions.EhcacheCollectionRegion;
29  import net.sf.ehcache.hibernate.strategy.EhcacheAccessStrategyFactory;
30  import net.sf.ehcache.hibernate.strategy.EhcacheAccessStrategyFactoryImpl;
31  import net.sf.ehcache.util.ClassLoaderUtil;
32  import net.sf.ehcache.util.Timestamper;
33  
34  import org.hibernate.cache.CacheDataDescription;
35  import org.hibernate.cache.CacheException;
36  import org.hibernate.cache.CollectionRegion;
37  import org.hibernate.cache.EntityRegion;
38  import org.hibernate.cache.QueryResultsRegion;
39  import org.hibernate.cache.RegionFactory;
40  import org.hibernate.cache.TimestampsRegion;
41  import org.hibernate.cache.access.AccessType;
42  import org.hibernate.cfg.Settings;
43  
44  import org.slf4j.Logger;
45  import org.slf4j.LoggerFactory;
46  
47  /***
48   * Abstract implementation of an Ehcache specific RegionFactory.
49   *
50   * @author Chris Dennis
51   * @author Greg Luck
52   * @author Emmanuel Bernard
53   * @author Abhishek Sanoujam
54   */
55  abstract class AbstractEhcacheRegionFactory implements RegionFactory {
56  
57      /***
58       * The Hibernate system property specifying the location of the ehcache configuration file name.
59       * <p/>
60       * If not set, ehcache.xml will be looked for in the root of the classpath.
61       * <p/>
62       * If set to say ehcache-1.xml, ehcache-1.xml will be looked for in the root of the classpath.
63       */
64      public static final String NET_SF_EHCACHE_CONFIGURATION_RESOURCE_NAME = "net.sf.ehcache.configurationResourceName";
65  
66      private static final Logger LOG = LoggerFactory.getLogger(AbstractEhcacheRegionFactory.class);
67  
68      /***
69       * MBean registration helper class instance for Ehcache Hibernate MBeans.
70       */
71      protected final ProviderMBeanRegistrationHelper mbeanRegistrationHelper = new ProviderMBeanRegistrationHelper();
72  
73      /***
74       * Ehcache CacheManager that supplied Ehcache instances for this Hibernate RegionFactory.
75       */
76      protected volatile CacheManager manager;
77  
78      /***
79       * Settings object for the Hibernate persistence unit.
80       */
81      protected Settings settings;
82  
83      /***
84       * {@link EhcacheAccessStrategyFactory} for creating various access strategies
85       */
86      protected final EhcacheAccessStrategyFactory accessStrategyFactory = new NonstopAccessStrategyFactory(
87              new EhcacheAccessStrategyFactoryImpl());
88  
89      /***
90       * Whether to optimize for minimals puts or minimal gets.
91       * <p>
92       * Indicates whether when operating in non-strict read/write or read-only mode
93       * Hibernate should optimize the access patterns for minimal puts or minimal gets.
94       * In Ehcache we default to minimal puts since this should have minimal to no
95       * affect on unclustered users, and has great benefit for clustered users.
96       * <p>
97       * This setting can be overridden by setting the "hibernate.cache.use_minimal_puts"
98       * property in the Hibernate configuration.
99       *
100      * @return true, optimize for minimal puts
101      */
102     public boolean isMinimalPutsEnabledByDefault() {
103         return true;
104     }
105 
106     /***
107      * {@inheritDoc}
108      */
109     public long nextTimestamp() {
110         return Timestamper.next();
111     }
112 
113     /***
114      * {@inheritDoc}
115      */
116     public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
117         return new EhcacheEntityRegion(accessStrategyFactory, getCache(regionName), settings, metadata, properties);
118     }
119 
120     /***
121      * {@inheritDoc}
122      */
123     public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata)
124             throws CacheException {
125         return new EhcacheCollectionRegion(accessStrategyFactory, getCache(regionName), settings, metadata, properties);
126     }
127 
128     /***
129      * {@inheritDoc}
130      */
131     public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
132         return new EhcacheQueryResultsRegion(accessStrategyFactory, getCache(regionName), properties);
133     }
134 
135     /***
136      * {@inheritDoc}
137      */
138     public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
139         return new EhcacheTimestampsRegion(accessStrategyFactory, getCache(regionName), properties);
140     }
141 
142     private Ehcache getCache(String name) throws CacheException {
143         try {
144             Ehcache cache = manager.getEhcache(name);
145             if (cache == null) {
146                 LOG.warn("Couldn't find a specific ehcache configuration for cache named [" + name + "]; using defaults.");
147                 manager.addCache(name);
148                 cache = manager.getEhcache(name);
149                 LOG.debug("started EHCache region: " + name);
150             }
151             HibernateUtil.validateEhcache(cache);
152             return cache;
153         } catch (net.sf.ehcache.CacheException e) {
154             throw new CacheException(e);
155         }
156 
157     }
158 
159     /***
160      * Load a resource from the classpath.
161      */
162     protected static URL loadResource(String configurationResourceName) {
163         ClassLoader standardClassloader = ClassLoaderUtil.getStandardClassLoader();
164         URL url = null;
165         if (standardClassloader != null) {
166             url = standardClassloader.getResource(configurationResourceName);
167         }
168         if (url == null) {
169             url = AbstractEhcacheRegionFactory.class.getResource(configurationResourceName);
170         }
171 
172             LOG.debug("Creating EhCacheRegionFactory from a specified resource: {}.  Resolved to URL: {}", configurationResourceName, url);
173         if (url == null) {
174 
175                 LOG.warn("A configurationResourceName was set to {} but the resource could not be loaded from the classpath." +
176                         "Ehcache will configure itself using defaults.", configurationResourceName);
177         }
178         return url;
179     }
180 
181     /***
182      * Default access-type used when the configured using JPA 2.0 config.  JPA 2.0 allows <code>@Cacheable(true)</code> to be attached to an
183      * entity without any access type or usage qualification.
184      * <p>
185      * We are conservative here in specifying {@link AccessType#READ_WRITE} so as to follow the mantra of "do no harm".
186      * <p>
187      * This is a Hibernate 3.5 method.
188      */
189     public AccessType getDefaultAccessType() {
190         return AccessType.READ_WRITE;
191     }
192 
193 }