2017-10-09 6 views
2

spring-boot-startter-data-jpa를 사용하는 Spring-Boot 응용 프로그램에서 Hibernate 2nd Level Cache를 활성화하려고합니다. 나는 또한이 같은 SRC/메인/자원 ehcache.xml을 만들어Spring-Boot - Hibernate 2nd Level Cache 활성화

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 

다음 속성 (A와 단지 테스트를 사용으로 Ehcache 2를 사용하고

내 클래스 경로에 최대 절전 모드-으로 Ehcache를 사용 기간 제한 없음 캐시)

<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의 REPO에 추가 편집 : https://gitlab.com/matrium00/reproduce-cache-issue

때문에 문제 지금 실패 이것에 대한 하나의 단위 테스트가있다. 여기

EDIT2

는 봄 부팅없이 그들을 공장 의 작업 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

당신은 (너무 @Transactional을 의미) 테스트 방법 및 @DataJpaTest@Transactional 주석이 당신의 테스트 클래스.

단일 트랜잭션이 있으므로 단일 세션이 있습니다. 동일한 트랜잭션 내에서 동일한 영속 객체에 접근 할 때, Hibernate는 첫 번째 레벨 캐시 (세션 캐시)를 사용한다. 두 번째 레벨 캐시에서 히트를 잡으려면 다른 세션 (다른 트랜잭션)이 있어야합니다.

@SpringBootTest으로 @DataJpaTest을 간단히 바꾸고 테스트 방법에서 @Transactional을 제거하면 테스트가 작동합니다.

은 참조 : 제 1 및 제 2 레벨의 캐시에 대한

+1

그래, 이미 이틀 전에 그걸 알아 냈어. 그래도 정답을 먼저주는 사람 이니 어쨌든 고맙습니다. –