Hibernate L2 Cache with Infinispan (Standalone)
What You Will Learn
How to configure Infinispan as the Hibernate second-level (L2) cache provider in a standalone Java SE application, and observe entity cache puts, hits, misses, and query cache behavior through Hibernate statistics.
Prerequisites
-
Java 17+
Step 1: Add the Infinispan Hibernate Cache Dependency
Add the Infinispan Hibernate cache module and an in-memory database to your pom.xml:
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-hibernate-cache-v66</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
Step 2: Configure the Persistence Unit
In META-INF/persistence.xml, enable the second-level cache and query cache, and set Infinispan as the cache provider:
<persistence-unit name="events">
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
<!-- H2 in-memory database -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.connection.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE"/>
<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<!-- Create/drop database in each run -->
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<!-- Enables second level cache -->
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<!-- Enable query cache -->
<property name="hibernate.cache.use_query_cache" value="true"/>
<!-- Use Infinispan second level cache provider -->
<property name="hibernate.cache.region.factory_class"
value="infinispan"/>
<!-- Force using local configuration when only using a single node.
Otherwise a clustered configuration is loaded. -->
<property name="hibernate.cache.infinispan.cfg"
value="org/infinispan/hibernate/cache/commons/builder/infinispan-configs-local.xml"/>
<!-- Generate statistics to see effects of second level cache -->
<property name="hibernate.generate_statistics" value="true" />
<!-- Entity specific configuration, e.g. via property:
hibernate.cache.infinispan.<Entity FQN>.expiration.max_idle
-->
<property name="hibernate.cache.infinispan.org.infinispan.tutorial.simple.hibernate.cache.local.model.Person.expiration.max_idle"
value= "1000"/>
</properties>
</persistence-unit>
Step 3: Mark Entities as Cacheable
Annotate your JPA entities with @Cacheable so they participate in second-level caching:
@Entity
@Cacheable
public class Event {
@Id
@GeneratedValue
private Long id;
private String name;
private LocalDateTime timestamp = LocalDateTime.now();
Step 4: Use the Entity Manager and Observe Cache Statistics
Persist, find, update, and query entities. Hibernate statistics reveal L2 cache activity:
// Create JPA persistence manager
emf = Persistence.createEntityManagerFactory("events");
CacheRegionStatistics eventCacheStats;
CacheRegionStatistics personCacheStats;
Statistics stats;
// Persist 3 entities, stats should show 3 second level cache puts
persistEntities();
eventCacheStats = getCacheStatistics(Event.class.getName());
printfAssert("Event entity cache puts: %d (expected %d)%n", eventCacheStats.getPutCount(), 3);
// Find one of the persisted entities, stats should show a cache hit
findEntity(1L);
eventCacheStats = getCacheStatistics(Event.class.getName());
printfAssert("Event entity cache hits: %d (expected %d)%n", eventCacheStats.getHitCount(), 1);
Step 5: Run the Tutorial
mvn package exec:exec
The output shows cache puts when entities are persisted, cache hits when entities are found, cache misses after eviction, and query cache behavior on repeated queries.
What’s Next
-
Hibernate L2 cache with Spring Boot for the same pattern in a Spring Boot application
-
Hibernate L2 cache with WildFly for a Jakarta EE deployment


