Redisson Hibernate 2L 缓存设置但始终执行 SQL 查询

Redisson Hibernate 2L cache setup but always executes SQL query

我正在尝试设置 Redisson Hibernate 2L 缓存,但我看到每次都执行休眠查询,即使结果清楚地缓存在我的 Redis 实例上也是如此。

调试时我可以看到它通过休眠并执行查询,然后按预期从 RedissonStorage.java 进入 putIntoCache。当我检查 Redis 时,我可以看到新的缓存值。但是,在随后调用我的服务时,它再次通过休眠 executeQueryStatement 进行完全相同的休眠查询,但有趣的是,它随后从 RedissonStorage.java 进入 getFromCache 并显示为 return 来自 Redis 的值。为什么它每次都执行查询而不是先检查redis?

appliation.yml

spring.profiles.active: local

server:
  port: 9000

spring:
  config:
    active:
      on-profile: local
  cache:
    type: redis

  jpa:
    database: POSTGRESQL
    generate-ddl: true
    properties:
      hibernate:
        jdbc:
          time_zone: UTC
        ddl-auto: create-drop
        show_sql: true
        cache:
          use_query_cache: true
          use_second_level_cache: true
          factory_class: org.redisson.hibernate.RedissonRegionFactory
          redisson:
            fallback: true
            config: redisson/redisson.yml
  datasource:
    platform: postgres
    url: jdbc:postgresql://localhost:5432/test
    username: postgres
    password: admin
    driverClassName: org.postgresql.Driver
    initialization-mode: always

redisson.yml

singleServerConfig:
  address: "redis://localhost:6379"

build.gradle

plugins {
    id 'org.springframework.boot' version '2.6.4'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.test'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-cache:2.6.4'

    implementation 'org.redisson:redisson-hibernate-53:3.16.8'

    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'org.postgresql:postgresql'

    compileOnly 'org.apache.logging.log4j:log4j-api:2.17.1'
    compileOnly 'org.apache.logging.log4j:log4j-core:2.17.1'

    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

实体class

@Data
@Entity
@Table(name = "employees")
@Cacheable
@Cache(region = "employeeCache", usage = CacheConcurrencyStrategy.READ_WRITE)
public class EmployeeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long employeeId;

    private String employeeName;
    private String employeeLastName;
}
@Component
public class EmployeeDAO {

    @Autowired
    private EmployeeRepository employeeRepository;

    public EmployeeEntity findByEmployeeId(Long employeeId) {
        return employeeRepository.findByEmployeeId(employeeId);
    }
@Repository
public interface EmployeeRepository extends CrudRepository<EmployeeEntity, Long> {

    EmployeeEntity findByEmployeeId(Long employeeId);
}

看起来 JPA 缓存适用于默认 findById 但不适用于 findAll 或自定义 findByType 或本例中的 findByEmployeeId.

但是,我找到了一种使用 @QueryHints 使其工作的方法。

import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import javax.persistence.QueryHint;

import static org.hibernate.jpa.QueryHints.HINT_CACHEABLE;

@Repository
public interface EmployeeRepository extends CrudRepository<EmployeeEntity, Long> {

    @QueryHints(value = { @QueryHint(name = HINT_CACHEABLE, value = "true")})
    EmployeeEntity findByEmployeeId(Long employeeId);

}