NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider means that a class compiled against Hibernate 3 runs with Hibernate 4 or newer, where the CacheProvider interface no longer exists. The interface CacheProvider was the Hibernate 3 plug-in point for a second level cache (a cache shared by all sessions), such as Ehcache 2. Hibernate 4.0 removed it and kept only RegionFactory.
We meet the error after a Hibernate upgrade that leaves a Hibernate 3 piece behind, in most projects either Spring’s orm.hibernate3.LocalSessionFactoryBean or an old hibernate-ehcache 3.x jar. We fix it by replacing the old piece with the one that matches our Hibernate version.
The following example shows the error for a Spring 3.2 app that runs with Hibernate 4.3 on Java 8, and for the same jars with Hibernate 7.4 on Java 25.
java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider;
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
at java.lang.Class.getDeclaredFields(Class.java:1916)
...
Caused by: java.lang.ClassNotFoundException: org.hibernate.cache.CacheProvider
java.lang.NoClassDefFoundError: org/hibernate/cache/CacheProvider
Caused by: java.lang.ClassNotFoundException: org.hibernate.cache.CacheProvider
Notice that Java 8 prints the L…; form, which is the JVM type descriptor of a field type, whereas Java 21 and 25 print the plain class name. Both messages point to the same missing interface. In a Spring application, the frame after getDeclaredFields() is often Spring’s PersistenceAnnotationBeanPostProcessor or AutowiredAnnotationBeanPostProcessor.
Next, we see which old jars still refer to CacheProvider and how to fix a Hibernate 4 or 5 project. After that, we move the cache to Hibernate 7 with JCache and Ehcache 3.
1. Why CacheProvider Cannot Be Found
The JVM throws NoClassDefFoundError when a class was present at compile time but is missing at runtime. The org/hibernate/cache folder of each hibernate-core jar on Maven Central shows when CacheProvider disappeared.
| Jar | CacheProvider | RegionFactory |
|---|---|---|
| hibernate 3.2.7.ga | Yes | No |
| hibernate-core 3.3.2.GA | Yes, deprecated | Yes |
| hibernate-core 3.6.10.Final | Yes, deprecated | Yes |
| hibernate-core 4.0.0.Final | No | Yes, in org.hibernate.cache.spi |
| hibernate-core 4.3.11, 5.6.15, 7.4.11 | No | Yes |
A region is a named cache, for example one per cached entity class. The RegionFactory creates the regions, and CacheProvider was its predecessor. Each Hibernate generation plugs Ehcache in differently.

Old jars that refer to the interface can still sit on the classpath. The JVM resolves the missing type lazily, so the error appears when some code first uses the old class.

1.1. Spring’s orm.hibernate3 Factory Bean
Up to Spring 4.3, spring-orm had one LocalSessionFactoryBean per Hibernate generation, in the packages orm.hibernate3, orm.hibernate4 and orm.hibernate5. The hibernate3 class declares a field of type CacheProvider, so loading the class works but reading its fields fails. Spring reads the fields of every bean class to find @Autowired and @PersistenceContext, so the context fails at startup.
Class<?> factoryBean = Class.forName("org.springframework.orm.hibernate3.LocalSessionFactoryBean"); // loads
Field[] fields = factoryBean.getDeclaredFields(); // NoClassDefFoundError: org/hibernate/cache/CacheProvider
We saw the same stack trace at the top of the article. The project moved to Hibernate 4 jars but kept the hibernate3 class name in its Spring XML.
1.2. A Hibernate 3 Ehcache Provider
Hibernate 3 projects configured Ehcache with hibernate.cache.provider_class, and the provider class came from hibernate-ehcache 3.x. The class EhCacheProvider implements CacheProvider, so the JVM cannot even load it.
Class<?> provider = Class.forName("org.hibernate.cache.EhCacheProvider");
// NoClassDefFoundError: org/hibernate/cache/CacheProvider
// Caused by: ClassNotFoundException: org.hibernate.cache.CacheProvider
When the old provider name is moved into the newer region.factory_class key, Hibernate 7 stops at startup. Hibernate tries several class loaders and attaches each NoClassDefFoundError as a suppressed exception.
org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.cache.spi.RegionFactory] due to: Unable to resolve name [org.hibernate.cache.EhCacheProvider] as strategy [org.hibernate.cache.spi.RegionFactory]
...
Caused by: java.lang.ClassNotFoundException: Could not load requested class: org.hibernate.cache.EhCacheProvider
Suppressed: java.lang.NoClassDefFoundError: org/hibernate/cache/CacheProvider
Caused by: java.lang.ClassNotFoundException: org.hibernate.cache.CacheProvider
2. How to Fix It
There is no jar to add, because Hibernate 4 and later never had CacheProvider. Instead, we remove every Hibernate 3 piece and use the class that matches the hibernate-core version.
| Old (Hibernate 3) | Hibernate 4.x and 5.x | Hibernate 6.x and 7.x |
|---|---|---|
| hibernate.cache.provider_class | hibernate.cache.region.factory_class | hibernate.cache.region.factory_class=jcache |
| org.hibernate.cache.EhCacheProvider | org.hibernate.cache.ehcache.EhCacheRegionFactory (short name ehcache) | JCacheRegionFactory (short name jcache) |
| org.hibernate:hibernate-ehcache:3.x | org.hibernate:hibernate-ehcache, same version as hibernate-core | org.hibernate.orm:hibernate-jcache plus org.ehcache:ehcache (classifier jakarta) |
| net.sf.ehcache (Ehcache 2) | net.sf.ehcache (Ehcache 2) | org.ehcache (Ehcache 3) |
| Spring orm.hibernate3.LocalSessionFactoryBean | orm.hibernate4 or orm.hibernate5.LocalSessionFactoryBean | orm.hibernate5 (Spring 6) or orm.jpa.hibernate (Spring 7) |
2.1. Fixing an Old Hibernate 4 or 5 Project
A legacy app that must stay on Hibernate 4 or 5 needs two changes. First, the Spring factory bean must come from the package that matches Hibernate.
<!-- Before: Hibernate 3 class, fails with Hibernate 4 jars -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- After: Hibernate 4 (use orm.hibernate5 for Hibernate 5) -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
Second, the cache setting moves from the provider to the region factory, and hibernate-ehcache takes the same version as hibernate-core.
# Before (Hibernate 3)
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
# After (Hibernate 4.x and 5.x, with org.hibernate:hibernate-ehcache)
hibernate.cache.use_second_level_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
With Hibernate 4.3.11.Final and 5.6.15.Final on Java 8, the second session reads the postal code from the cache (hits=1, one SELECT), and the short name ehcache gives the same result. Keeping only provider_class is not a fix. Hibernate 4.3 then fails with NoCacheRegionFactoryAvailableException, and Hibernate 5.6 with Caching was explicitly requested, but no RegionFactory was defined.
Hibernate 5.6 logs HHH020100: The Ehcache second-level cache provider for Hibernate is deprecated. The hibernate-ehcache module has no final 6.x release, so this setup is a dead end and we should plan the move to JCache.
2.2. Moving to Hibernate 7 With JCache and Ehcache 3
Hibernate 7 reaches Ehcache 3 through JCache (JSR-107), the standard caching API in the javax.cache package. The following example caches a postal code lookup, which a delivery app runs on every checkout although the data changes only a few times a year. A PostalCode has a code (“560001”), a town (“Bengaluru”) and a district (“Bengaluru Urban”). The example runs on Java 25, Hibernate 7.4.11.Final, Ehcache 3.12.0 and an in-memory H2 database. The following dependencies replace hibernate-ehcache.
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>7.4.11.Final</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.12.0</version>
<classifier>jakarta</classifier>
<exclusions>
<exclusion>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</exclusion>
</exclusions>
</dependency>
The settings select the jcache region factory and point Ehcache to its ehcache.xml, which declares one cache per region. We bootstrap with HibernatePersistenceConfiguration.
.property("hibernate.cache.region.factory_class", "jcache")
.property("hibernate.javax.cache.provider", "org.ehcache.jsr107.EhcacheCachingProvider")
.property("hibernate.javax.cache.uri", "ehcache.xml")
.property("hibernate.javax.cache.missing_cache_strategy", "fail")
.property("hibernate.generate_statistics", true)
@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class PostalCode {
@Id
private String code;
private String town;
private String district;
}
In Spring Boot 4, the same keys go into application.properties with the spring.jpa.properties. prefix. The statistics prove that the cache works, because the second session finds the postal code in Ehcache and sends no SQL.
Statistics stats = emf.unwrap(SessionFactory.class).getStatistics();
emf.getCache().evictAll();
stats.clear();
emf.runInTransaction(em -> em.find(PostalCode.class, "560001"));
// select pc1_0.code,pc1_0.district,pc1_0.town from PostalCode pc1_0 where pc1_0.code=?
// L2 hits=0, misses=1, puts=1, statements=1
emf.runInTransaction(em -> em.find(PostalCode.class, "560001"));
// no SQL
// L2 hits=1, misses=1, puts=1, statements=1
With Ehcache 3 on Hibernate 6 and 7, every region name needs a cache in ehcache.xml, and each missing piece fails with its own error. Expiry and heap sizing go into the Hibernate Ehcache configuration.
The complete project on GitHub reproduces both errors with the real hibernate-ehcache 3.6.10 and Spring 3.2 jars in test scope, with 11 JUnit tests that check every result (mvn -q test-compile exec:java, mvn test).
3. CacheProvider Error FAQs
3.1. Does Hibernate 7 Still Read hibernate.cache.provider_class?
No. Hibernate 7 ignores the key and logs nothing about it, so even a class that does not exist lets the EntityManagerFactory start normally.
.property("hibernate.cache.use_second_level_cache", true)
.property("hibernate.cache.provider_class", "org.example.NoSuchProvider") // starts, no error
// region factory: JCacheRegionFactory
The cache still worked, but only because hibernate-jcache was the single region factory on the classpath, and Hibernate picks that one by itself. So we delete the old key, and nobody is misled into thinking it controls the cache.
3.2. Why Does Hibernate 7 Reject EhCacheRegionFactory?
The Hibernate 4 and 5 names belong to the hibernate-ehcache module, which does not exist for Hibernate 6 and 7. Both names fail at startup, whereas jcache starts.
| hibernate.cache.region.factory_class | Root cause on Hibernate 7.4 |
|---|---|
| org.hibernate.cache.ehcache.EhCacheRegionFactory | ClassNotFoundException: Could not load requested class: org.hibernate.cache.ehcache.EhCacheRegionFactory |
| ehcache | ClassNotFoundException: Could not load requested class: ehcache |
| jcache | Starts, with hibernate-jcache on the classpath |
3.3. How Do I Find the Jar That Still Uses CacheProvider?
The Hibernate 3 to 5 jars use the group id org.hibernate, while Hibernate 6 and 7 use org.hibernate.orm. Filtering the Maven dependency tree on the old group id and on spring-orm lists the suspects.
mvn dependency:tree -Dincludes=org.hibernate,org.springframework:spring-orm
[INFO] com.howtodoinjava:hibernate-cacheprovider-error:jar:1.0.0
[INFO] +- org.hibernate:hibernate-ehcache:jar:3.6.10.Final:test
[INFO] \- org.springframework:spring-orm:jar:3.2.18.RELEASE:test
In the example, both jars are there on purpose. In a real project, any org.hibernate jar next to hibernate-core 6 or 7, or a spring-orm older than the rest of Spring, has to be removed or upgraded.
4. Conclusion
The error NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider comes from a version mix. A Hibernate 3 class runs with Hibernate 4 or newer, where CacheProvider was replaced by RegionFactory. Old projects fix it with the Spring factory bean and the EhCacheRegionFactory that match their Hibernate version. On Hibernate 7, we remove every Hibernate 3 and hibernate-ehcache piece, add hibernate-jcache with Ehcache 3, set region.factory_class to jcache, and check the hit count in the statistics.
5. References
- Hibernate ORM 7.4 User Guide: JCache
- Hibernate ORM 7.4 User Guide: Caching configuration properties
- RegionFactory JavaDoc (Hibernate 7.4)
- Statistics JavaDoc (Hibernate 7.4)
- CacheProvider JavaDoc (Hibernate 3.6)
- Hibernate 4.3 Developer Guide: Caching
- LocalSessionFactoryBean JavaDoc (Spring Framework 7)
- Ehcache 3 JCache (JSR-107) Provider
Happy Learning !!
What about AnnotationSessionFactoryBean configurarion in spring.xml?