Saltar al contenido

Spring Boot + JPA2 + Hibernate: habilita la caché de segundo nivel

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *