Estoy tratando de configurar Hibernate con Ehcache como el caché de segundo nivel, pero el TTL no está funcionando.
Aquí están mis dependencias:
<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>
Aquí está mi configuración 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
Así es como se configura mi clase de entidad:
@Entity
@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class PersonEntity {
//
}
Y el JpaRepository para la entidad:
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);
}
He configurado el caché expira en 2 segundos, pero llamar findByName
todavía utiliza la memoria caché (no hay consultas SQL impresas después de la primera).
Aquí está el ehcache.xml
archivo:
<?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: He hecho algunas depuración. He añadido un punto de quiebre en org.ehcache.jsr107.ExpiryPolicyToEhcacheExpiry
:
javax.cache.expiry.Duration duration = this.expiryPolicy.getExpiryForCreation();
Esta duración es infinito por alguna razón. Así que tal vez la configuración no está ajustado correctamente? Sé que el XML se está leyendo porque cuando lo invalidan (mediante la eliminación de la etiqueta del montón por ejemplo) me da un error.
Creo que he encontrado la causa del problema - que no especifica una ubicación del ehcache.xml
archivo:
spring:
jpa:
properties:
hibernate:
javax.cache:
provider: org.ehcache.jsr107.EhcacheCachingProvider
uri: classpath:ehcache.xml
cache:
use_second_level_cache: true
region.factory_class: jcache
use_query_cache: true
en este caso, Hibernate crea una caché con la configuración por defecto. Un fragmento de mi registro de proyectos de demostración:
17:15:19 WARN [main] org.hibernate.orm.cache: HHH90001006: Missing cache[user] was created on-the-fly. The created cache will use a provider-specific default configuration: make sure you defined one. You can disable this warning by setting 'hibernate.javax.cache.missing_cache_strategy' to 'create'.