package com.ankurm.hibernatedemo.cache; import static org.assertj.core.api.Assertions.assertThat; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.junit.jupiter.api.Test; /** * Checks the original article's claim -- "Missing default-update-timestamps-region: Required for * the Query Cache -- omitting it causes startup errors" -- by actually omitting it, rather than * repeating the warning unverified. The claim is FALSE for this stack: {@code SessionFactory} * builds with no error at all. * *
{@code hibernate-jcache}'s default {@code MissingCacheStrategy} is {@code CREATE_WARN} * (external representation {@code "create-warn"}, confirmed by disassembling {@code * MissingCacheStrategy.class} in {@code hibernate-jcache-7.4.5.Final.jar}): a missing region is * created on the fly with provider-specific default policies, and Hibernate only logs {@code * HHH90001006}. Setting {@code hibernate.javax.cache.missing_cache_strategy} to {@code "fail"} * turns this into the hard startup error the article describes; {@code "create"} keeps the * auto-create behavior but silences the warning. * *
Docs: docs/18-ehcache-l2-configuration.md */ class MissingUpdateTimestampsRegionTest { @Test void queryCacheEnabled_withNoUpdateTimestampsRegionInEhcacheXml_buildsFineWithOnlyAWarning() { StandardServiceRegistry registry = new StandardServiceRegistryBuilder() .applySetting("hibernate.connection.driver_class", "org.h2.Driver") .applySetting("hibernate.connection.url", "jdbc:h2:mem:missingtimestamps;DB_CLOSE_DELAY=-1") .applySetting("hibernate.connection.username", "sa") .applySetting("hibernate.hbm2ddl.auto", "create") .applySetting("hibernate.cache.use_second_level_cache", "true") .applySetting("hibernate.cache.use_query_cache", "true") .applySetting("hibernate.cache.region.factory_class", "jcache") .applySetting("hibernate.javax.cache.provider", "org.ehcache.jsr107.EhcacheCachingProvider") .applySetting("hibernate.javax.cache.uri", "ehcache-chapter18-missing-timestamps.xml") .build(); try { Metadata metadata = new MetadataSources(registry) .addAnnotatedClass(CacheProduct.class) .buildMetadata(); Throwable thrown = catchThrowableFromBuildSessionFactory(metadata); System.out.println("RESULT[cache-missing-timestamps-region]: " + (thrown == null ? "SessionFactory built with NO error -- contrary to the original article, the " + "default MissingCacheStrategy (CREATE_WARN) auto-creates the missing " + "default-update-timestamps-region and only logs HHH90001006" : thrown.getClass().getName() + ": " + rootMessage(thrown))); assertThat(thrown) .as("corrected finding: with the default missing_cache_strategy, a missing " + "default-update-timestamps-region does NOT fail SessionFactory startup") .isNull(); } finally { StandardServiceRegistryBuilder.destroy(registry); } } @Test void settingMissingCacheStrategyToFail_reproducesTheHardStartupErrorTheArticleDescribed() { StandardServiceRegistry registry = new StandardServiceRegistryBuilder() .applySetting("hibernate.connection.driver_class", "org.h2.Driver") .applySetting("hibernate.connection.url", "jdbc:h2:mem:missingtimestampsfail;DB_CLOSE_DELAY=-1") .applySetting("hibernate.connection.username", "sa") .applySetting("hibernate.hbm2ddl.auto", "create") .applySetting("hibernate.cache.use_second_level_cache", "true") .applySetting("hibernate.cache.use_query_cache", "true") .applySetting("hibernate.cache.region.factory_class", "jcache") .applySetting("hibernate.javax.cache.provider", "org.ehcache.jsr107.EhcacheCachingProvider") .applySetting("hibernate.javax.cache.uri", "ehcache-chapter18-missing-timestamps.xml") .applySetting("hibernate.javax.cache.missing_cache_strategy", "fail") .build(); try { Metadata metadata = new MetadataSources(registry) .addAnnotatedClass(CacheProduct.class) .buildMetadata(); Throwable thrown = catchThrowableFromBuildSessionFactory(metadata); System.out.println("RESULT[cache-missing-timestamps-region-strict]: " + "hibernate.javax.cache.missing_cache_strategy=fail -> " + (thrown == null ? "SessionFactory built with NO error" : thrown.getClass().getName() + ": " + rootMessage(thrown)) + " -- this is how to opt into the hard-failure behavior the original article assumed " + "was the default."); assertThat(thrown) .as("with missing_cache_strategy explicitly set to fail, a missing " + "default-update-timestamps-region does cause a startup error -- this is an " + "opt-in, not the default") .isNotNull(); } finally { StandardServiceRegistryBuilder.destroy(registry); } } private static Throwable catchThrowableFromBuildSessionFactory(Metadata metadata) { try { metadata.buildSessionFactory().close(); return null; } catch (Throwable t) { return t; } } private static String rootMessage(Throwable t) { Throwable cause = t; while (cause.getCause() != null) { cause = cause.getCause(); } return cause.getMessage(); } }