我有一个PostgreSQL 9.3.6数据库,定义了以下查询:
CREATE OR REPLACE VIEW calls_today AS
SELECT
cc.*
FROM
call_config cc
WHERE
cc.created_at >= current_date;
该视图用于通过JPA 2使用Play Framework + Hibernate开发的Web门户。除了与日期相关的查询外,一切似乎都正常。
如果今天重新启动服务器,该视图看起来像工作,但只在今天。明天,我将在网页上看到过去两天的所有电话。第二天,另外一个,所以三天等等。 如果我在psql客户端上发出查询,结果就好了,只是当天。
我必须遗漏一些东西,它看起来不像查询结果被缓存(因为每天结果都会增长),而是在服务器重启的那天修复了 current_date 。就像某种准备好的陈述一样,我真的不知道。
使用以下JPA 2 API从数据库中提取数据:
private static<T extends IOutgoingCallConfig> Result getCalls(Class<T> entityClass) {
Check.Argument.isNotNull(entityClass, "entityClass");
List<CallItem> calls = new ArrayList<>();
EntityManager em = JPA.em();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> cq = cb.createQuery(entityClass);
Root<T> rootEntry = cq.from(entityClass);
CriteriaQuery<T> all = cq.select(rootEntry);
TypedQuery<T> allQuery = em.createQuery(all);
for(T entity: allQuery.getResultList()) {
calls.add(new CallItem(entity));
}
return jsonSuccess(calls);
}
我已经通过psql测试了以下准备好的查询:
prepare mystmt as select current_time;
不会遇到这个问题。每次执行都会显示更新的当前服务器时间:
execute mystmt;
拥有如下的简单视图:
CREATE OR REPLACE VIEW my_current_time as select current_time;
导致同样的问题。一个查询已运行,返回值始终相同:(
它可能与current_time和current_date的定义有关。 来自PostgreSQL 9.4 documentation:
由于这些函数返回当前事务的开始时间,因此它们的值在事务期间不会更改。这被认为是一个特征:目的是允许单个事务具有“当前”时间的一致概念,以便同一事务中的多个修改具有相同的时间戳。
答案 0 :(得分:0)
原来是交易范围问题。 我的控制器注释为:
@Transactional(readOnly=true)
因为它只读取数据。由于某种原因,交易范围涵盖所有未来的请求:(我在这里有点惊讶。我希望每个请求都有一个事务或者根本没有(自动提交事务)。
我已经改变了
current_date
与
date_trunc('day', clock_timestamp())
现在它甚至可以通过Hibernate运行。
我想我必须阅读更多关于Hibernate和JPA 2的内容,否则如果我不清楚地了解交易范围,我可能会遇到类似的问题。