简体   繁体   中英

Caching not working with Spring 3.0, Hibernate 3.6, and EhCache 2.6.6

We're trying to get caching working in our app and are having a very hard time getting it to actually work. We don't have a very complex configuration, at least for this part of the application, so it's really frustrating and I finally have to throw myself on the tender mercies of the StackOverflow community.

First, for now, we're stuck at Spring 3.0 and Hibernate 3.6, so using the new Spring 3.1 @Cacheable annotations and all that other stuff isn't an option for us.

I've put the versions of our stack in the subject and what we have is a very typical configuration for that stack:

  • Our Hibernate entities are just defined with @Entity, DAOs with @Repository, and services with @Service
  • Transactional boundaries are set with @Transactional
  • I've added in caching by adding ehcache-core to the pom.xml and adding the following properties to the Hibernate properties map:
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory</prop>

I then added the @Cache annotation to my entity classes, something like this:

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "config")
public class Configuration extends AbstractHibernateEntity implements Serializable {

And to be honest, I thought I was done. Yay me for configuring caching so easily! And you could see it working, there were lots of messages in the logs as caching came online. That's great!

Only it turns out that caching has come online and nothing is getting cached. I've now been pounding on this for two days and have no clue why my objects are not getting cached. I've tried added <cache name="..."/> into my ehcache.xml , specifying regions on my @Cache annotations, checking the cache statistics, etc. I've added debug logging for both the net.sf.ehcache and org.hibernate.cache packages. I simply don't see what's keeping this from saving objects out to the cache and accessing them there.

After we realized our web application wasn't caching, I went back into the dependent libraries and realized that they weren't caching either (I added caching to the unit tests to make sure that caching didn't break the unit tests; it doesn't but maybe that's just because it's not caching). So I've been working on one of our lower-level dependencies, figuring if I could figure out how to make it work at that level, I could pull that up to the web app level. That's a great theory except that I can't even make it work at the lower level!

In my logs, I'm getting lots of messages. So here's a sample of the debug output from net.sf.ehcache :

14:03:20,795  INFO                           net.sf.ehcache: 284 - CACHE HITS:  0
14:03:20,796  INFO                           net.sf.ehcache: 284 - IN-MEM HITS: 0
14:03:20,796  INFO                           net.sf.ehcache: 284 - CACHE MISS:  0
14:03:20,796  INFO                           net.sf.ehcache: 284 - IN-MEM MISS: 0
14:03:20,796  INFO                           net.sf.ehcache: 284 - EVICTIONS:   0
14:03:20,797  INFO                           net.sf.ehcache: 284 - MEM OBJ CT:  0
14:03:20,886 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration_data value: 5643835231789056
14:03:20,890 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration value: 5643835231805440
14:03:20,891 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration_data value: 5643834986045441
14:03:20,891 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration value: 5643834986045441
14:03:20,897 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration_data value: 5643835231834112
14:03:20,898 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration value: 5643835231838208
14:03:20,898 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration_data value: 5643834986078209
14:03:20,899 DEBUG bernate.regions.EhcacheGeneralDataRegion: 211 - key: xhbm_configuration value: 5643834986078209

And in the org.hibernate.cache log, I get lots of stuff like this:

14:47:26,077 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration_data]
14:47:26,081 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration]
14:47:26,082 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration_data], timestamp: 5643845820751872
14:47:26,082 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration], timestamp: 5643845820751872
14:47:26,089 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration_data]
14:47:26,091 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration]
14:47:26,092 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration_data], timestamp: 5643845820792832
14:47:26,092 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration], timestamp: 5643845820792832
14:47:26,125 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration_data]
14:47:26,130 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Pre-invalidating space [xhbm_configuration]
14:47:26,131 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration_data], timestamp: 5643845820952576
14:47:26,132 DEBUG rg.hibernate.cache.UpdateTimestampsCache: 168 - Invalidating space [xhbm_configuration], timestamp: 5643845820952576

I really don't know what else to say about it from here. The full code is available both from my Bitbucket repo (it's Mercurial, not git) at https://bitbucket.org/rherrick/nrg_config or as a zip from Dropbox at https://dl.dropboxusercontent.com/u/42711610/nrg_config.zip . You should just be able to run the unit tests from Maven with:

mvn clean install

If anyone could help me figure out what the hell's going wrong here, I'd be ecstatically happy! And don't you want me to be ecstatically happy? I know I do :)

Seriously, many thanks in advance and many thanks will follow afterwards for any help with this issue.

As far as I understand second-level cache for objects will be used only when you call load get , list etc on Session . I can't see in your code such calls.

Query cache will be used only when you call setCacheable on Query or Criteria object. And again, you never call that method in your code.

Alexander,

You're on the right track, but that was only one factor among a few that caused the problem. There were really three factors going on:

  1. Our code actually is calling load(), get(), list(), etc., but it's mostly wrapped up in our framework code. I went through and templatized a bunch of that code to explicitly force caching there. That started SOME caching.
  2. JPA/Hibernate entities should NEVER initialize ANYTHING! We had a base class that set a couple of flags and timestamps on instantiation. When an object was retrieved, this ended up making the object look dirty and in need of a full run out to the database. This was really the big one for our framework.
  3. Watching out for transactional boundaries when setting transient properties. When you go into and then out of a method marked @Transactional, any changes to your objects will be persisted, regardless of whether you called a session.save() on that object or not, as described here . This was causing objects to constantly fail to match against the cached version (although I'd have thought the modified version of the object would match caching, but that didn't seem to happen).

In the end, this ended up being really difficult to diagnose primarily because it wasn't one single factor, but caused by lots of different things together!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM