Hibernate has a number of options for configuring its second level cache. For more information on configuring this, you might want to read John Ferguson Smart's article titled Speed Up Your Hibernate Applications with Second-Level Caching.
Up until today, I thought EhCache was the default cache provider, but apparently not anymore. From Hibernate's documentation:
Note that versions prior to 3.2 defaulted to use EhCache as the default cache provider; that is no longer the case as of 3.2.
So what's the default now? It can't be Hashtable since that's not for production use. I doubt it's OSCache since OSCache can't even get its patches into Hibernate. Looking through the release notes, I found out it's NoCacheProvider - seemingly because of an issue with EhCache:
Due to the upgrade to EhCache1.2 and its new non-singleton cache setup, we should no longer default the cache provider to be ehcache. Instead, default to NoCacheProvider.
That's reasonable I guess. EhCache added support for distributed caching in 1.2. It's a shame they didn't maintain backwards compatibility or they'd still be the default caching provider. Regardless, it doesn't matter who the default caching provider is because it's very easy to change it. Here's how it's configured on one of my projects:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=${hibernate.dialect}
hibernate.query.substitutions=true 'Y', false 'N'
hibernate.cache.use_second_level_cache=true
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
</value>
</property>
</bean>
Of course, you can also configure it directly in hibernate.cfg.xml or a hibernate.properties file.
This leads me to the reason for this post:
What is the best 2nd level (clustered) cache to use for Hibernate?
I'm sure some folks will say Coherence, so let's narrow the question to what's the best open source option?
I've used OSCache in the past. It worked well, but it was kind of annoying that I had to patch Hibernate to make it work. The Hibernate folks say it's OSCache's fault, the OSCache guys say it's Hibernate's fault - so this issue will likely never get resolved. So what about EhCache? I don't know, I've only used it in a single JVM environment and haven't tried it in a clustered environment. Is there anyone using Hibernate + EhCache in production that can verify its effectiveness?
Of the options listed in Hibernate's documentation, the only other options seem to be JBoss TreeCache and SwarmCache. You can quickly eliminate SwarmCache since it never made it past 1.0 RC2 in October of 2003.
That leaves JBoss TreeCache, EhCache and OSCache as choices for a clusterable 2nd-level cache. OSCache is an invalidating cache, which definitely works - but might not work as you expect it to. JBoss Cache only seems to allow a replicated cache which also works. EhCache seems to support both. I don't know if invalidating or replicating is better, but I imagine replicating can get quite chatty if you're dealing with large amounts of data.
But wait - is there another open source option? According to Terracotta's CTO, Terracotta is much faster than JBoss Cache. However, if you read about it on DZone, you'll see that JBoss Cache has no "official" benchmarks.
So what's a developer to do? My current client likes OSCache, but I'm leaning towards EhCache. Which would you recommend?
Of course, if Coherence is only $1K per CPU, maybe that's the obvious choice? Unfortunately, I couldn't find their pricing using Google.