【发布时间】:2015-09-11 16:23:23
【问题描述】:
我遇到了一个问题,我的查询方法位于 foreach 循环中,并且每次我传入不同的参数以检索不同的信息。但是,在循环的第一次迭代之后,查询数据被缓存(我认为)并为后续循环返回相同的数据。
这是我的代码:
@Transactional(readOnly = true)
public List<InitiativeReport> getInitiativeReports() throws Exception {
try {
List<InitiativeReport> ir = new ArrayList<InitiativeReport>();
List<Initiative> in = initiativeRepository.findAll();
for(Initiative i : in) {
i.getTheme().getId(); // lazy initialize
InitiativeReport report = new InitiativeReport();
report.setId(i.getId());
report.setInitiativeId(i.getInitiativeId());
report.setName(i.getName());
report.setTheme(i.getTheme());
// this is the call to the query, which is cached after the first iteration
List<InitiativeProfileQuestion> q = initiativeProfileQuestionRepository.getQuestionsAndAnswerLogs(i.getInitiativeId());
report.setQuestions(q);
ir.add(report);
}
return ir;
}
catch (Exception e) {
throw new Exception(e);
}
这是我的仓库界面:
public interface InitiativeProfileQuestionRepository extends JpaRepository<InitiativeProfileQuestion, Long> {
@Query("select distinct q from InitiativeProfileQuestion q "
+ "left join fetch q.answers "
+ "left join fetch q.answerLogs al "
+ "where al.initiative.initiativeId = ?1 "
+ "and al.revision = al.initiative.revision
+ "order by q.question asc")
public List<InitiativeProfileQuestion> getQuestionsAndAnswerLogs(String initiativeId);
}
这是我的 application.yml 文件:
spring:
datasource:
dataSourceClassName: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
url: jdbc:mysql://localhost/testdb
username: root
password: XXXXXXXXX
driverClassName: com.mysql.jdbc.Driver
testOnBorrow: true
validationQuery: SELECT 1
jpa:
database-platform: org.hibernate.dialect.MySQLInnoDBDialect
database: MYSQL
openInView: false
show_sql: true
generate-ddl: false
hibernate:
ddl-auto: none
naming-strategy: org.hibernate.cfg.EJB3NamingStrategy
这个问题与我在这里找到的帖子非常相似:Native Query (JPA ) not reset and return the same old result
但是,该用户正在使用 EntityManager,而我的应用程序中没有 EntityManager 的实现——我让 JPA 完成所有工作,并且只有查询注释。
任何帮助将不胜感激!
【问题讨论】:
-
向我们展示课程 InitiativeReport
-
我在上面添加了 InitiativeReport 和 InitiativeProfileQuestion
-
而调用的 SQL 是?在日志中,这可能会告诉您是否将正确的参数传递给它
-
SQL 正确。我知道这是因为如果我执行单独的 GET 请求,每个请求都运行一次查询方法,它们会返回正确的值。但是,在单个 GET 请求中完成所有操作(使用 for 循环)往往会缓存结果。我还用不同的参数测试了日志中显示的查询,它可以工作。所以某处发生了某种奇怪的缓存——我只是不知道在哪里可以找到它,或者我可以做些什么来禁用它。
-
我认为应用程序可能正在为我的 JPA 查询使用 EntityManager,它正在实现一级缓存。我不确定如何清除它,因为我没有在我的 spring 应用程序的任何地方显式调用 EntityManager。
标签: java spring hibernate jpa spring-data