2017-10-09 157 views
2

我試圖在使用spring-boot-starter-data-jpa的Spring-Boot應用程序上激活Hibernate二級緩存。我使用了Ehcache 2和具有休眠-的Ehcache在我的類路徑爲Spring-Boot - 激活休眠二級緩存

我用下面的性質

spring.jpa.properties.hibernate.cache.use_second_level_cache=true 
spring.jpa.properties.hibernate.cache.use_query_cache=true 
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory 
spring.jpa.properties.hibernate.generate_statistics=true 

而且我創建ehcache.xml中的SRC /主/資源像這樣(只是一個測試緩存永不過期)

<ehcache updateCheck="false" monitoring="autodetect" 
    dynamicConfig="true"> 

    <defaultCache 
     maxElementsInMemory="100000" 
     maxElementsOnDisk="10000000" 
     eternal="true" 
     overflowToDisk="false"> 
    </defaultCache> 
</ehcache> 

而且實體標註有@Cache(usage = CacheConcurrencyStrategy.READ_WRITE),並在日誌文件中,我可以清楚地看到,默認緩存用於實體,所以它似乎認識到了註釋和初始化緩存如常。

WARN .h.c.e.AbstractEhcacheRegionFactory : HHH020003: Could not find a specific ehcache configuration for cache named [at.test.demo.persistence.entity.Employee]; using defaults. 

現在來測試這個我寫了一個簡單的測試,使用通常的JPA的EntityManager的插入部分3名的員工並加載它們。之後,我試圖通過調用下面的命令來驗證加載的Employee實際上是否真的進入緩存:

Assert.assertTrue(em.getEntityManagerFactory().getCache().contains(Employee.class, employeeId)); 

但是這總是失敗。 SessionFactory-Staticstics也顯示了一切的零,這是不對的。

任何想法?

編輯 我剝了下來該項目,並把它添加到公共gitlab回購爲您重現:https://gitlab.com/matrium00/reproduce-cache-issue

有這個一個單元測試,現在失敗了,因爲這個問題的。

EDIT2 這裏是EM-工廠的工作XML配置的不彈簧啓動的例子。我知道我可以創造我的手動配置級必要的豆,但必須有一個更好的辦法:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
     autowire="byName" depends-on="flyway"> 
    <property name="packagesToScan" value="at.my.package.demo.persistence.entity"/> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="jpaProperties"> 
     <props> 
      <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
      <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> 
      <prop key="hibernate.default_schema">${jdbc.schema}</prop> 

      <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop> 
      <prop key="hibernate.cache.use_second_level_cache">true</prop> 
      <prop key="hibernate.cache.use_query_cache">true</prop> 
      <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop> 
     </props> 
    </property> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> 
    </property> 
</bean> 
+0

配置看起來不錯。你能提供一些示例代碼嗎? –

+0

我編輯我的問題,並添加了一個示例項目的gitlab鏈接 –

回答

2

你有你的測試方法和@DataJpaTest(這意味着@Transactional太)的@Transactional標註上你測試班。

由於只有一個事務,所以會有一個會話。當你在同一個事務中訪問同一個持久化對象時,Hibernate使用第一級緩存(會話緩存)。要在二級緩存中擊中,應該有不同的會話(不同的事務)。

簡單替換@DataJpaTest@SpringBootTest並從測試方法中刪除@Transactional使測試工作。

參見:

+1

是的,我已經弄清楚了兩天前。你仍然是第一個給出正確答案的人,所以無論如何謝謝你 –