Solución:
Para resumir todo (caché L2 y caché de consultas):
Lo primero que debe hacer es agregar el proveedor de caché (recomiendo usar EhCache) a su classpath.
Hibernar <5.3
Añade el hibernate-ehcache
dependencia. Esta biblioteca contiene EhCache 2, que ahora está descontinuada.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>your_hibernate_version</version>
</dependency>
Hibernar> = 5.3
En versiones más recientes de cachés de Hibernate, se debe usar la API JSR-107 (JCache). Por lo tanto, se necesitan 2 dependencias: una para la API JSR-107 y la segunda para la implementación real de JCache (EhCache 3).
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jcache</artifactId>
<version>your_hibernate_version</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.6.3</version>
<scope>runtime</scope>
</dependency>
Ahora pasemos al archivo application.properties/yml:
spring:
jpa:
#optional - show SQL statements in console.
show-sql: true
properties:
javax:
persistence:
sharedCache:
#required - enable selective caching mode - only entities with @Cacheable annotation will use L2 cache.
mode: ENABLE_SELECTIVE
hibernate:
#optional - enable SQL statements formatting.
format_sql: true
#optional - generate statistics to check if L2/query cache is actually being used.
generate_statistics: true
cache:
#required - turn on L2 cache.
use_second_level_cache: true
#optional - turn on query cache.
use_query_cache: true
region:
#required - classpath to cache region factory.
factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory
Para EhCache 3 (o Hibernar> = 5.3) esta fábrica de región debe utilizarse:
factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
También puede habilitar el registro de nivel de TRACE para que Hibernate verifique su código y configuración:
logging:
level:
org:
hibernate:
type: trace
Ahora pasemos al código. Para habilitar el almacenamiento en caché L2 en su entidad, debe agregar esas dos anotaciones:
@javax.persistence.Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) //Provide cache strategy.
public class MyEntity {
...
}
Nota – si desea almacenar en caché su @OneToMany
o @ManyToOne
relación – agregar @Cache
anotación sobre este campo también.
Y para habilitar el caché de consultas en su repositorio spring-data-jpa, debe agregar el QueryHint
.
public class MyEntityRepository implements JpaRepository<MyEntity, Long> {
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<MyEntity> findBySomething(String something);
}
Ahora verifique a través de registros si su consulta se ejecuta solo una vez y recuerde apagar todas las cosas de depuración, ahora ya está.
Nota 2 – también puede definir la estrategia de caché faltante como create
si desea permanecer con los valores predeterminados sin recibir advertencias en sus registros:
spring:
jpa:
properties:
hibernate:
javax:
cache:
missing_cache_strategy: create
Bueno, después de investigar un poco más, esto es lo que me faltaba application.properties
:
spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
Espero que ayude a alguien 🙂
@Daimon No estoy realmente seguro de si
spring.jpa.properties.javax.persistence.sharedCache.mode=ALL
es la mejor decisión.
Citado de Hibernate 20.2.1. Sección de documentación de asignaciones de caché
De forma predeterminada, las entidades no forman parte de la caché de segundo nivel y le recomendamos que se ciña a esta configuración. Sin embargo, puede anular esto configurando el elemento shared-cache-mode en su archivo persistence.xml o usando la propiedad javax.persistence.sharedCache.mode en su configuración.
mientras que
ENABLE_SELECTIVE (valor predeterminado y recomendado): las entidades no se almacenan en caché a menos que se marquen explícitamente como almacenables en caché.
Entonces, ¿podría ser que no ha anotado todas las entidades afectadas con @ javax.persistence.Cacheable o más bien @ org.hibernate.annotations.Cache? Esto podría provocar el efecto de que el caché de consultas intentó buscar las entidades afectadas en el caché de segundo nivel sin éxito y luego comenzó a buscar cada entidad con una sola selección.