How to cache results of a Spring Data JPA query method without using query cache?

后端 未结 3 1324
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-12 20:00

I have a Spring Boot app with Spring Data JPA (hibernate backend) repository classes. I\'ve added a couple custom finder methods, some with specific @Query anno

3条回答
  •  长情又很酷
    2020-12-12 20:03

    First I quote your question:

    What am I doing wrong?

    The way you are trying to name the cache is not appropriate to how hibernate will use it. Check org.hibernate.engine.spi.CacheInitiator which uses org.hibernate.internal.CacheImpl which is based on:

    if ( settings.isQueryCacheEnabled() ) {
        final TimestampsRegion timestampsRegion = regionFactory.buildTimestampsRegion(
                qualifyRegionName( UpdateTimestampsCache.REGION_NAME ),
                sessionFactory.getProperties()
        );
        updateTimestampsCache = new UpdateTimestampsCache( sessionFactory, timestampsRegion );
        ...
    }
    

    And UpdateTimestampsCache.REGION_NAME (equals to org.hibernate.cache.spi.UpdateTimestampsCache) is what you are missing as the cache name. For the query cache you'll have to use exactly that cache name and no other!

    Now few other thoughts related to your problem:

    • removing @Cache and setting cache name to org.hibernate.cache.spi.UpdateTimestampsCache will allow your query to be cached with ehcache by hibernate (spring cache abstraction is not involved here)
    • setting a hardcoded cache name won't make you happy I'm sure but at least you know why this happens
    • Balamaci Serban (the post just below) is painfully right

    Below is the configuration from one of my projects where ehcache + @Query + @QueryHints work as expected (ehcache/ehcache-in-memory.xml file):

    
    
        
    
        
    
        
    
        
    
        
    
    

    and hibernate.properties:

    hibernate.jdbc.batch_size=20
    hibernate.show_sql=true
    hibernate.format_sql=true
    hibernate.validator.autoregister_listeners=false
    hibernate.cache.use_second_level_cache=true
    hibernate.cache.use_query_cache=true
    hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
    hibernate.hbm2ddl.auto=update
    net.sf.ehcache.configurationResourceName=ehcache/ehcache-in-memory.xml
    hibernate.dialect=org.hibernate.dialect.H2Dialect
    

    and some versions from pom.xml for which my explanation applies:

    5.0.6.RELEASE
    5.0.5.RELEASE
    2.1.0.RELEASE
    5.2.13.Final
    2.9.4
    

    And the full working test is image.persistence.repositories.ImageRepositoryTest.java found here: https://github.com/adrhc/photos-server/tree/how-to-cache-results-of-a-spring-data-jpa-query-method-without-using-query-cache
    Yep, run mvn clean install or change my env.sh if you really want to use my shell scripts. Check then the number of sql queries on behalf of 3x imageRepository.count() call.

提交回复
热议问题