2015-07-23 6 views
12

Ich benutze Spring Boot 1.2.5 mit JPA2, um Entitäten zu kommentieren (und Hibernate als unterliegende JPA-Implementierung).Spring Boot + JPA2 + Hibernate - Aktivieren Sie den Second Level Cache

I Cache zweiter Ebene in diesem Setup verwenden wollte so Entitäten kommentierten wurden mit @javax.persistence.Cacheable

Ich habe auch in application.properties folgende:

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 

während des Systemstarts Hibernate über Mangel an EhCacheRegionFactory beschwert so ich habe auch dies pom:

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

Aber immer noch fragt, wie entityManager.find(Clazz.class, pk) sind Auslösen einer DB-Abfrage, anstatt zwischengespeicherte Daten zu verwenden.

Irgendeine Idee, was fehlt?

+1

Ich hoffe, Sie haben das Caching-Management aktiviert, in Ihrer Konfigurationsklasse mit '@ EnableCaching' oder in der XML-Datei mit' '. – Arpit

+0

Obwohl es nur für Spring Caching verwendet wird - ich möchte JPA2 Caching verwenden (Frage aktualisieren, um anzugeben, dass ich '@ javax.persistence.Cacheable' verwende) auf Klassenebene – Daimon

Antwort

19

Nun, nachdem einige mehr hier zu graben ist, was ich in application.properties fehlt:

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

Hoffe, dass es jemand hilft :)

+0

Thx Daimon, und für jeden, der so weit kommt, ist es erwähnenswert, dass Sie beide Konfiguration von der Frage benötigen, zusätzlich zu der Konfiguration dieser Antwort. – Xiangyu

+6

Es ist vorzuziehen, 'spring.jpa.properties.javax.persistence.sharedCache.mode = ENABLE_SELECTIVE' zu setzen, da nur dann Ihre' @ javax.persistence.Cacheable' Annotationen berücksichtigt werden. –

+0

Ich habe das Problem gelöst, indem ich diese Eigenschaft gesetzt habe: hibernate.cache.region.factory_class –

0

Sie sollten eine ehcache.xml-Datei in Ihrem Klassenpfad haben. Die Datei sollte mindestens die Standard-Cache-Strategie enthalten. Zur leichteren Debugging, macht es ewig sicher Entitäten werden nicht aus dem Cache vertrieben:

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" 
... 
/> 

Um sicherzustellen, dass alles ok ist, sollten Sie das folgende Protokoll während Ihres Starts der Anwendung haben:

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

Das bedeutet, dass Ihre Entity-Cache-Annotation korrekt gelesen wurde und der Standard-Cache verwendet wird.

Wenn Sie mit entityManager.find(Clazz.class, pk) testen, ist dies nicht der Abfragecache, sondern nur der Entitätscache. Query-Cache für Abfragen (em.createQuery (...) und für die Beziehungen Schiff verwendet

Auch ich org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory verwenden, aber ich weiß nicht, wich ist besser.

+1

Während es ratsam ist,' ehcache.xml' zu haben, es ist keineswegs notwendig. Ehcache wird die Standard-Cache-Konfiguration verwenden, die Ihnen 10.000 Elemente und eine TTL von 120s gibt - das ist nicht abgestimmt, aber es ist ein Ausgangspunkt, der für viele gut genug ist. Beachten Sie auch, dass es nicht ausreicht, die Datei "ehcache.xml" zu verwenden. Sie müssen auch die richtigen Caches definieren, um alle Warnungen zu entfernen. –

6

@Daimon ich nicht wirklich sicher bin, ob

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

ist die beste Entscheidung.

Zitat von Hibernate 20.2.1. Cache mappings documentation section

Standardmäßig sind Einheiten, die Teil der zweiten Ebene Cache nicht und wir empfehlen Ihnen, diese Einstellung zu bleiben. Sie können dies jedoch überschreiben, indem Sie das Element shared-cache-mode in Ihrer Datei persistence.xml oder mithilfe der Eigenschaft javax.persistence.sharedCache.mode in Ihrer Konfiguration festlegen.

während

ENABLE_SELECTIVE (Standard- und empfohlene Wert): Einheiten zwischengespeichert werden, wenn diese explizit als zwischenspeicherbar markiert.

So könnte es sein, dass Sie nicht alle betroffenen Einheiten mit @ javax.persistence.Cacheable kommentiert haben oder eher @ org.hibernate.annotations.Cache? Dies könnte dazu führen, dass der Query-Cache versucht, die betroffenen Entitäten im Second-Level-Cache erfolglos nachzuschlagen und dann jede Entity durch eine einzelne select abzurufen.

+0

Nein, das war nicht der Fall. spring.jpa.properties.javax.persistence.sharedCache.mode muss explizit eingestellt werden. Ob ALL oder andere Einstellung, das ist eine andere Geschichte und nicht auf dieses Problem selbst bezogen – Daimon

+1

Um meine zwei Cents hinzuzufügen: Mit Spring Boot 1.4 und Ehcache und Hibernate 5.1 müssen Sie wirklich mindestens die Region Factory und den Shared-Cache-Modus einstellen. Selbst wenn "ENABLE_SELECTIVE" als Standard dokumentiert ist, musste ich es explizit auf diesen Wert setzen. –

0

Haben Sie hinzufügen

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

auf die Klasse, die Sie gecached werden sollen?

Verwandte Themen