Case i want to recreate:
- Application startup and put one table from postgres DB to cache
- All querys to this table must be executed and use second level cache instead of DB connection.
build.gradle:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.hibernate.orm:hibernate-jcache:6.1.6.Final'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.ehcache:ehcache:3.10.8'
}
application.properties:
spring.jpa.show-sql=true
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.generate_statistics=true
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=
org.hibernate.cache.jcache.JCacheRegionFactory
spring.jpa.hibernate.ddl-auto=none
Cache initialization:
@Configuration
public class CacheConfig {
private final RegionsRepo repo;
public CacheConfig(RegionsRepo repo) {
this.repo = repo;
}
@PostConstruct
public void initCache() {
repo.findAll().forEach(region -> {});
}
}
And JpaRepository:
public interface RegionsRepo extends JpaRepository<Regions, Long> {
Optional<Regions> findRegionsByExternalid(Integer id);
@Override
Optional<Regions> findById(Long aLong);
@Override
@QueryHints(@QueryHint(name = org.hibernate.annotations.QueryHints.CACHEABLE, value = "true"))
List<Regions> findAll();
}
After starup app puts table into second level hibernate cache. Log:
346333 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
73250 nanoseconds spent preparing 1 JDBC statements;
1098084 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
5962251 nanoseconds spent performing 3 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
368667 nanoseconds spent performing 1 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
68458 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
when i call repository method
findById
which is Overrided from JpaRepository, i see that there is no execution of JDBC statement, just pure L2C hits which is what i needed.
Log:
1277291 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
0 nanoseconds spent preparing 0 JDBC statements;
0 nanoseconds spent executing 0 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
418709 nanoseconds spent performing 1 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
BUT when i use custom, not overrided method
findRegionsByExternalid
L2C is ignored. Log:
742083 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
849083 nanoseconds spent preparing 1 JDBC statements;
2029042 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
670583 nanoseconds spent performing 1 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
Could you please tell what is wrong with hibernate cache configuration in this case?