Spring Boot + JPA2 + Hibernate-включить кэш второго уровня

Я использую Spring Boot 1.2.5 с JPA2 для аннотирования сущностей (и спящий режим как подложка реализации JPA).

Я хотел использовать кэш второго уровня в этой настройке, поэтому сущности были аннотированы @javax.persistence.Cacheable

Я также добавил следующее в приложение.свойства:

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.EhCacheRegionFactory

во время загрузки hibernate жаловался на отсутствие EhCacheRegionFactory поэтому я также добавил Это в pom:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
</dependency>

но все же запросы, такие как entityManager.find(Clazz.class, pk) вместо этого запускают запрос DB использования кэшированных данных.

есть идеи, чего не хватает?

5 ответов


Ну после еще нескольких раскопок вот что мне не хватало в application.properties:

spring.jpa.properties.javax.persistence.sharedCache.mode=ALL

надеюсь, это поможет кому-то:)


@Daimon Я не совсем уверен, что

spring.jpa.properties.javax.persistence.sharedCache.mode=ALL

- лучшее решение.

цитата из спящий режим 20.2.1. Раздел документации по сопоставлениям кэша

по умолчанию объекты не являются частью кэша второго уровня и мы рекомендуем вам придерживаться этого параметра. Однако вы можете переопределить это, установив элемент режима общего кэша в сохраняемости.xml-файл или с помощью класса javax.стойкость.sharedCache.свойство mode в вашей конфигурации.

, тогда как

ENABLE_SELECTIVE (по умолчанию и рекомендуемое значение): сущности не кэшируются, если явно не помечены как кэшируемые.

таким образом, может быть, вы не аннотировали все затронутые объекты с помощью @javax.стойкость.Cacheable или, скорее, @org.зимовать.комментарии.Кэш ? Это может привести к тому, что кэш запросов попытается найти затронутый сущности в кэше второго уровня без успеха, а затем начали получать каждую сущность одним выбором.


вы добавили

@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY) 

в классе, который вы хотите кэшировать?


у вас должен быть ehcache.XML-файл в classpath. Файл должен содержать по крайней мере стратегию кэша по умолчанию. Для облегчения отладки сделайте вечным, чтобы убедиться, что сущности не выселяются из кэша:

ehcache.XML-код:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:noNamespaceSchemaLocation="ehcache.xsd"
  Name="CacheManager" 
  maxBytesLocalHeap="250m">

<defaultCache eternal="true"
...
/>

<cache name="org.hibernate.cache.internal.StandardQueryCache"
       eternal="true"
...
/>

чтобы убедиться, что все в порядке, вы должны иметь следующий журнал во время запуска приложения:

Could not find a specific ehcache configuration for cache named [com.yourcompany.YourClass]; Using defaults.

это означает, что ваша аннотация кэша сущностей была правильно прочитана и кэш по умолчанию будет используемый.

Если вы испытываете с entityManager.find(Clazz.class, pk) это не envolve кэш запросов, а только кэш сущностей. Кэш запросов используется для запросов (em.createQuery(...) а для отношений корабль

кроме того, я использую org.зимовать.кэш.ehcache.SingletonEhCacheRegionFactory, но я не знаю, что лучше.


вы можете использовать стороннего поставщика кэша, среди JCache, Ehcache, Gvava Cache, Hazelcast Cache, Caffeine Cache.

пожалуйста, обратитесь к этому ответу на очередную статью чтобы узнать, как включить и настроить кэш второго уровня в Spring boot.