Kevin M
Kevin M

Reputation: 2903

Why am I seeing cache misses against the UpdateTimestampsCache?

Could someone please explain to me why when using the ehCache monitor am I seeing cache misses against the UpdateTimestampsCache? I don't see misses against any of my other caches, and actually I don't see any cached entries in the UpdateTimestampsCache.... I must be doing SOMETHING wrong. FYI, may application is a Spring Boot application using Spring Data JPA and a couple custom finder methods in a couple repositories that I've tagged as cacheable. I have query caching enabled. I have query cache and updatetimestampscache configured in ehcache.xml:

<cache name="org.hibernate.cache.internal.StandardQueryCache" maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="3600"
   overflowToDisk="true" diskSpoolBufferSizeMB="20" memoryStoreEvictionPolicy="LFU" transactionalMode="off"
   statistics="true"/>
<cache name="org.hibernate.cache.spi.UpdateTimestampsCache" maxEntriesLocalHeap="10000" timeToIdleSeconds="3600"
       eternal="true" overflowToDisk="true" diskSpoolBufferSizeMB="20" memoryStoreEvictionPolicy="LFU" transactionalMode="off"
       statistics="true">
</cache>

Here's an example of one of my Repository classes and a custom finder method:

public interface PromotionServiceXrefRepository extends PagingAndSortingRepository<PromotionServiceXref, Integer> {
    @Query("SELECT psx FROM Customer c " +
            "JOIN c.customerProductPromotions cpp " +
            "JOIN cpp.productPromotion pp " +
            "JOIN pp.promotion p JOIN p.promotionServiceXrefs psx " +
            "WHERE c.sonosId = ?1")
    @QueryHints(@QueryHint(name = "org.hibernate.cacheable", value = "true"))
    @Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region = "promotionServiceXrefByCustomerId")
    Set<PromotionServiceXref> findByCustomerId(int customerId);
}

Upvotes: 0

Views: 274

Answers (1)

Alex
Alex

Reputation: 166

My guess is that Hibernate does not put timestamps in the "default-update-timestamps-region" unless a modification is made to the table (update, insert, delete). So, initially the region is empty and read-only tables are never timestamped. That, in turn, means the query cache will not work with these entities since it cannot tell if the table has been updated (cause no timestamp).

Theoretically, you could try pre-populating the region upon startup with something like this:

final var cachingProvider = Caching.getCachingProvider();
final var cacheManager = cachingProvider.getCacheManager();
final var updateTimestampsCache =
    cacheManager.getCache(RegionFactory.DEFAULT_UPDATE_TIMESTAMPS_REGION_UNQUALIFIED_NAME);
updateTimestampsCache.put("MY_TABLE", SimpleTimestamper.next());

Upvotes: 0

Related Questions