JPA Hibernate PostgreSQL current_date 不工作
JPA Hibernate PostgreSQL current_date doesn't work
我有一个 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 开发的门户网站。除了与日期相关的查询外,一切似乎都运行良好。
如果服务器今天重新启动,视图看起来像在工作,但只是在今天。明天,我将在网页上看到过去两天的所有通话。第二天,又一个,三天等等。
如果我在 psql 客户端上发出查询,结果很好,只是当天。
我一定是遗漏了什么,查询结果看起来并没有被缓存(结果每天都在增长),而是 current_date 固定在服务器重启之日。像某种prepared statement,我真的不知道。
使用以下 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;
导致同样的问题。其中一个查询是 运行,return 值始终相同 :(
可能与current_time和current_date的定义有关。
来自 PostgreSQL 9.4 documentation:
Since these functions return the start time of the current transaction, their values do not change during the transaction. This is considered a feature: the intent is to allow a single transaction to have a consistent notion of the "current" time, so that multiple modifications within the same transaction bear the same time stamp.
原来是事务作用域问题。
我的控制器注释为:
@Transactional(readOnly=true)
因为它只读取数据。出于某种原因,事务范围涵盖所有未来的请求:( 我在这里有点惊讶。我希望每个请求都有一个事务或者根本没有(自动提交事务)。
我变了
current_date
与
date_trunc('day', clock_timestamp())
现在 运行即使通过 Hibernate 也很好。
我想我必须阅读更多有关 Hibernate 和 JPA 2 的信息,否则如果我不清楚事务范围,我可以 运行 解决类似的问题。
我有一个 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 开发的门户网站。除了与日期相关的查询外,一切似乎都运行良好。
如果服务器今天重新启动,视图看起来像在工作,但只是在今天。明天,我将在网页上看到过去两天的所有通话。第二天,又一个,三天等等。 如果我在 psql 客户端上发出查询,结果很好,只是当天。
我一定是遗漏了什么,查询结果看起来并没有被缓存(结果每天都在增长),而是 current_date 固定在服务器重启之日。像某种prepared statement,我真的不知道。
使用以下 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;
导致同样的问题。其中一个查询是 运行,return 值始终相同 :(
可能与current_time和current_date的定义有关。 来自 PostgreSQL 9.4 documentation:
Since these functions return the start time of the current transaction, their values do not change during the transaction. This is considered a feature: the intent is to allow a single transaction to have a consistent notion of the "current" time, so that multiple modifications within the same transaction bear the same time stamp.
原来是事务作用域问题。 我的控制器注释为:
@Transactional(readOnly=true)
因为它只读取数据。出于某种原因,事务范围涵盖所有未来的请求:( 我在这里有点惊讶。我希望每个请求都有一个事务或者根本没有(自动提交事务)。
我变了
current_date
与
date_trunc('day', clock_timestamp())
现在 运行即使通过 Hibernate 也很好。
我想我必须阅读更多有关 Hibernate 和 JPA 2 的信息,否则如果我不清楚事务范围,我可以 运行 解决类似的问题。