J'essaie de configurer l'hibernation avec Ehcache comme le cache de deuxième niveau, mais le TTL ne fonctionne pas.
Voici mes dépendances:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
Voici ma configuration YAML:
spring:
jpa:
show-sql: true
properties:
hibernate:
dialect: Dialect
cache:
use_second_level_cache: true
region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
use_query_cache: true
cache:
jcache:
config: classpath:ehcache.xml
Voici comment ma classe d'entité est configurée:
@Entity
@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class PersonEntity {
//
}
Et le jParepository pour l'entité:
public interface PersonRepository extends JpaRepository<PersonEntity, Integer> {
@org.springframework.data.jpa.repository.QueryHints({
@javax.persistence.QueryHint(name = "org.hibernate.cacheable", value = "true")
})
List<PersonEntity> findByName(String name);
}
J'ai configuré le cache pour expirer dans 2 secondes, mais appeler findByName
_ utilise toujours le cache (il n'y a pas de requêtes SQL imprimées après la première).
Ici se trouve le ehcache.xml
déposer:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://www.ehcache.org/v3">
<cache-template name="simple">
<expiry>
<ttl>2</ttl>
</expiry>
<heap>100</heap>
</cache-template>
<cache alias="com.sample.PersonEntity" uses-template="simple"/>
</config>
Edit: J'ai fait du débogage. J'ai ajouté un point de pause dans org.ehcache.jsr107.ExpiryPolicyToEhcacheExpiry
:
javax.cache.expiry.Duration duration = this.expiryPolicy.getExpiryForCreation();
Cette durée est infinie pour une raison quelconque. Alors peut-être que la configuration n'est pas définie correctement? Je sais que le XML est en train d'être lu parce que lorsque je l'invalide (en supprimant la balise de tas par exemple), je reçois une erreur.
Quand vous définissez votre @Cacheable
Annotation sur votre entité Il crée une région où le KEY
est le ID
de l'entité et le Value
est l'entité. Ce qui précède signifie que vous allez frapper le cache si vous accédez par clé qui est le ID
. Si vous utilisez des données de printemps et de la FindbyID, il frappera le cache. Si vous créez une méthode FindbyName, l'accès ne sera pas à l'aide de la clé, il ne frappera pas la région de cache définie par votre Cacheable
annotation. D'autre part, il frappera le cache de requête, mais le cache de requête est dans une région entièrement différente. Et juger de votre configuration Vous n'avez pas configuré le cache de requête à l'ensemble .Pour cette méthode pour toucher n'importe quel cache, vous devez l'ajouter à l'aide de cette propriété:
spring:jpa:properties:hibernate:cache:use_query_cache: true
Alternativement, vous pouvez spécifier @cacheable en haut de la méthode du référentiel de cette manière définir une nouvelle région.
Vous pouvez configurer le cache par défaut, cela devrait capter la StandardQuiseryCahache.
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600">
</defaultCache>
Dans eHCache2, vous pouvez configurer le cache de requête standard via cet élément:
<cache
name="org.hibernate.cache.internal.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600">
Je ne sais pas comment il est dans ehcache 3 cependant. Je crois que cela devrait être le même, car la classe StandartqueryCache fait partie du forfait Hibernate et ne fait pas partie du paquet EHCache.
Je pense aussi que vous avez besoin de définir
[.____] hibernate.javax.cache.provider = org.ehcache.jsr107.ehcachecachingProvider