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);
}
我正在尝试设置 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);
}