Class EhcacheConfig

java.lang.Object
ubic.gemma.persistence.cache.EhcacheConfig

@Configuration public class EhcacheConfig extends Object
Spring application-cache configuration backed by Ehcache 3 (jakarta classifier) via JCache (JSR-107).

History: Phase 1 retired the old Ehcache 2.x stack. Until this commit the bean named ehcache was a ConcurrentMapCacheManager stub — a HashMap-backed CacheManager that auto-creates caches on demand with no heap cap, TTL, or eviction policy. Every consumer (aclCache, OutlierDetailsCache, ExpressionExperimentReportsCache, the OntologyService.* caches, GeneOntologyService.*, Gene2GoServiceCache, DiffExResultCache, TopDiffExResultCache, and the two ProcessedExpressionDataVector* caches) silently received unbounded HashMap-backed stores — a latent memory-leak vector in production.

This config replaces the stub with a real JCacheCacheManager. Each named application cache is declared programmatically with a bounded heap and a TTL via CacheConfigurationBuilder (wrapped in Eh107Configuration for JSR-107).

Hibernate L2 regions are also pre-declared here. The same JCache provider (EhcacheCachingProvider) backs both the Spring application caches and Hibernate's JCacheRegionFactory (see applicationContext-hibernate.xml). Although Hibernate constructs its own javax.cache.CacheManager instance, the Ehcache provider returns the same underlying CacheManager for the same URI — so caches pre-created here are visible to Hibernate's L2 lookups. Without pre-declaration, Hibernate's missing_cache_strategy=create would lazily create each region with the JCache provider's defaults, which for Ehcache 3 means unbounded heap with no TTL — the same latent memory-leak vector as the App-cache stub had. The missing_cache_strategy=create setting is retained as a safety net: any region not enumerated here still works, just unbounded; the enumerated ones are bounded.

Sizes and TTLs below are conservative starting points sourced from the legacy (Ehcache 2.x) ehcache.xml where overlap exists, the Hibernate L2 cache audit (see HIBERNATE_L2_CACHE_AUDIT.md on worktree-hibernate-l2-tune), and common-sense defaults otherwise. TODO: per-cache tuning informed by production traffic.

Follow-up unblocked by this change: a MeterRegistryJCacheConfigurer binding io.micrometer.core.instrument.binder.cache.JCacheMetrics per named cache, restoring the cache-metrics flow that was dropped in Phase 2 when MeterRegistryEhcacheConfigurer (Ehcache 2.x API) was deleted. The JCache CacheManager produced here is the right target for that binder; that work is tracked separately in MetricsConfig.

  • Constructor Details

    • EhcacheConfig

      public EhcacheConfig()
  • Method Details

    • jCacheCacheManager

      @Bean(destroyMethod="close") public javax.cache.CacheManager jCacheCacheManager()
      The single JCache CacheManager shared by Spring's application-cache abstraction. Hibernate constructs its own JCache CacheManager internally via the same provider (see applicationContext-hibernate.xml), so the two are not the same instance but share the underlying Ehcache provider.
    • ehcache

      @Bean(name="ehcache") public org.springframework.cache.CacheManager ehcache(javax.cache.CacheManager jcache)
      Spring's facade over the JCache CacheManager. Preserves the bean name ehcache so legacy XML wiring (depends-on="ehcache") and existing field injections resolve unchanged.