Skip to main content

Ehcache 3.8 Documentation

1. Configuring Ehcache

To start using Ehcache, you need to configure your first CacheManager and Cache. This can be done through programmatic configuration or XML.

If you want to use JSR-107, i.e., the javax.cache API, you should first read the Ehcache 3.x JSR-107 Provider page.

1.1 Programmatic Configuration

Java configuration is easiest using builders that provide a fluent API.

As with earlier versions of Ehcache, the canonical way to handle Cache is through CacheManager.

// This static method org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder returns a new org.ehcache.config.builders.CacheManagerBuilder instance
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
// Use the builder to define a cache aliased "preConfigured".
// This cache will be created when cacheManager.build() is called on the actual CacheManager instance.
// The first String argument is the cache alias, used to retrieve the cache from CacheManager.
// The second argument, org.ehcache.config.CacheConfiguration, is used to configure the cache. We use the static newCacheConfigurationBuilder() method from org.ehcache.config.builders.CacheConfigurationBuilder to create a default configuration.
.withCache("preConfigured",
CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)))
// Finally, calling build() returns a fully instantiated but uninitialized CacheManager.
.build();
// Before using CacheManager, it needs to be initialized using one of these 2 methods:
// Call CacheManager.init() on the CacheManager instance, or call CacheManagerBuilder.build(boolean init) with boolean parameter set to true.
cacheManager.init();
// Retrieve the cache by passing its alias, key type and value type to CacheManager.
// For example, to get the cache declared in step 2, use alias="preConfigured", keyType=Long.class and valueType=String.class.
// For type safety, we require passing both key and value types.
// If these differ from what we expect, CacheManager throws ClassCastException early in the application lifecycle.
// This prevents the cache from being polluted with random types.
Cache<Long, String> preConfigured =
cacheManager.getCache("preConfigured", Long.class, String.class);
// You can create new Cache instances as needed using CacheManager.
// Like in step 2, it requires passing an alias and CacheConfiguration.
// The instantiated and fully initialized Cache will be returned and/or accessed through CacheManager.getCache API.
Cache<Long, String> myCache = cacheManager.createCache("myCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)));
// The newly added cache can now store entries consisting of key-value pairs. The first parameter of put is the key, the second is the value.
// Remember that key and value types must match those defined in CacheConfiguration.
// Also, keys must be unique and associated with only one value.
myCache.put(1L, "da one!");
// Retrieve values from cache by calling cache.get(key).
// It takes only one parameter as key and returns the value associated with that key.
// Returns null if no value is associated with that key.
String value = myCache.get(1L);
// We can CacheManager.removeCache(String) a given cache.
// CacheManager will not only remove its reference to the Cache but also close it.
// The cache releases all locally held transient resources (e.g., memory).
// References to this cache become unusable.
cacheManager.removeCache("preConfigured");
// To release all transient resources (memory, threads, etc.) provided by CacheManager to Cache instances it manages, you must call CacheManager.close(), which in turn closes all Cache instances known at that time.
cacheManager.close();

Below is a shorter version with three important things:

// CacheManager implements Closeable, so it can be auto-closed via try-with-resources.
// CacheManager must be fully closed.
// In a finally block, using try-with-resources or (more common in regular applications) in some shutdown hook.
try(CacheManager cacheManager = newCacheManagerBuilder()
// Builders with different names can use static imports.
.withCache("preConfigured", newCacheConfigurationBuilder(Long.class, String.class, heap(10)))
// Use build(true) to initialize CacheManager.
.build(true)) {

// Same code as before [...]
}

1.2 XML Configuration

You can create an XML file to configure CacheManager.

<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd">
<!-- Declare a Cache aliased foo. -->
<cache alias="foo">
<!-- foo's key and value are declared as String type; -->
<!-- If not specified, default is java.lang.Object. -->
<key-type>java.lang.String</key-type>
<value-type>java.lang.String</value-type>
<resources>
<!-- Declare foo can hold up to 2,000 entries on heap... -->
<heap unit="entries">20</heap>
<!-- ...and up to 500 MB of off-heap memory before GC reclaims -->
<offheap unit="MB">10</offheap>
</resources>
</cache>
<!-- <cache-template> element allows creating an abstract configuration that further <cache> configurations can "extend" -->
<cache-template name="myDefaults">
<key-type>java.lang.Long</key-type>
<value-type>java.lang.String</value-type>
<heap unit="entries">200</heap>
</cache-template>
<!-- bar is such a cache. bar uses <cache-template> named myDefaults and overrides its key type to a more custom type. -->
<cache alias="bar" uses-template="myDefaults">
<key-type>java.lang.Number</key-type>
</cache>
<!-- simpleCache is another such Cache. It uses myDefaults configuration as its only CacheConfiguration. -->
<cache alias="simpleCache" uses-template="myDefaults" />

</config>

For more details on XML format, see XML documentation

To parse XML configuration, use XmlConfiguration type:

// Get URL pointing to your XML file location
URL myUrl = getClass().getResource("/my-config.xml");
// Instantiate XmlConfiguration passing XML file URL
Configuration xmlConfig = new XmlConfiguration(myUrl);
// Using static org.ehcache.config.builders.CacheManagerBuilder.newCacheManager(org.ehcache.config.Configuration), you can create CacheManager instance using Configuration from XmlConfiguration
CacheManager myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);

1.3 Creating a Cache Manager with Clustering Support

To enable Terracotta clustering, first you must start a Terracotta server configured with cluster storage. Also, to create a cache manager with clustering support, you'll need to provide cluster service configuration:

// Returns org.ehcache.config.builders.CacheManagerBuilder instance;
CacheManagerBuilder<PersistentCacheManager> clusteredCacheManagerBuilder =
CacheManagerBuilder.newCacheManagerBuilder()
// Use ClusteringServiceConfigurationBuilder's static method .cluster(URI) to connect cache manager to cluster storage via specified URI, which returns cluster service configuration builder instance.
// The sample URI in this example points to cluster storage on Terracotta server with cluster storage identifier my-application (assuming server runs on localhost port 9410);
// auto-create query-param creates cluster storage in server.
.with(ClusteringServiceConfigurationBuilder.cluster(URI.create("terracotta://localhost/my-application"))
// Returns a fully initialized cache manager that can be used to create clustered caches.
.autoCreate(c -> c));
// Auto-create cluster storage if it doesn't exist yet.
PersistentCacheManager cacheManager = clusteredCacheManagerBuilder.build(true);
// Close cache manager.
cacheManager.close();

For more information on this feature, see Clustered Cache documentation.

1.4 Storage Tiers

As with previous versions, Ehcache 3 provides a tiered model that stores more and more data on slower tiers (usually more abundant). The idea is that resources associated with faster storage are scarcer, but they're where preferred "hottest" data resides. Thus, less hot (less used) data moves to richer but slower tiers. Hotter data moves to faster tiers.

1.4.1 Three Tiers

A classic example is using Three Tiers with persistent disk storage.

// If you want to use disk storage (e.g., for persistent Cache instances), you must provide a location to CacheManagerBuilder.persistence() static method where data should be stored on disk.
PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.with(CacheManagerBuilder.persistence(new File(getStoragePath(), "myData")))
.withCache("threeTieredCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
// You define resource pool for heap. This will be your faster but smaller pool.
.heap(10, EntryUnit.ENTRIES)
// You can define resource pool for offheap. Still quite fast, and larger.
.offheap(1, MemoryUnit.MB)
// You define a persistent resource pool for disk. Persistent because it should be (last parameter is true).
.disk(20, MemoryUnit.MB, true)
)
).build(true);
Cache<Long, String> threeTieredCache = persistentCacheManager.getCache("threeTieredCache", Long.class, String.class);
// After JVM restart, all values stored in cache will be available (assuming CacheManager was cleanly closed by calling close()).
threeTieredCache.put(1L, "stillAvailableAfterRestart");

persistentCacheManager.close();

For details, read Tiering documentation.

1.4.2 Data Freshness

In Ehcache, data updates are controlled through Expiry. Below illustrates how to configure time-to-live.

// Expiry is configured at cache level, so first define cache configuration
CacheConfiguration<Long, String> cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.heap(100))
// Then add expiry to it, here using predefined time-to-live and configuring desired duration.
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(20)))
.build();

For more information on available options, see Expiry section.

2. Advanced Topics

Many advanced topics discussed here have been moved out, see below.

2.1 User Managed Caches

For more information on this feature, see User Managed Cache documentation

2.2 Byte-Sized Heap

For more information on this feature, see relevant section in Tiering documentation.

2.3 Update ResourcePools

For more information on this feature, see relevant section in Tiering documentation.

2.4 Off-Heap Memory

For more information on this feature, see Tiering documentation.

2.5 Disk Persistence

For more information on this feature, see Tiering documentation.