2015-04-24 4 views
0

У меня есть база данных PostgreSQL 9.3.6 с помощью следующего запроса: определенJPA Hibernate PostgreSQL текущая_дата не работает

CREATE OR REPLACE VIEW calls_today AS 
SELECT 
    cc.* 
FROM 
    call_config cc 
WHERE 
    cc.created_at >= current_date; 

Вид используется на веб-портал, разработанный с Play Framework + Hibernate с помощью JPA 2. Кажется, что все работает отлично, за исключением запросов, связанных с датой.

Если сервер перезагружен сегодня, представление выглядит как работающее, но только сегодня. Завтра я увижу на веб-странице все звонки за последние два дня. На следующий день, еще один, так что три дня и так далее. Если я выдаю запрос клиенту 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

Во-первых, пожалуйста, ответьте на вопрос - меняется ли запрос (TABLE calls_today) из дня в день? Если да, это проблема спящего режима/JPA, если нет - postgres. – Eugene

+0

Только что проверили ваше представление my_current_time на моей установке postgresql 9.4. При запросе представления из pgAdmin значение в представлении обновляется, как ожидалось. Так что это проблема спящего режима. Возможно, кэширование, поэтому попробуйте переключить это. Вероятно, вы также можете зарегистрировать все запросы, чтобы увидеть, действительно ли он запрашивает представление. – Eelke

+0

Да, представление работает нормально. Возвращаются только сегодняшние звонки. – aguyngueran

ответ

0

Оказалось, что проблема с транзакцией. Мой контроллер с аннотацией:

@Transactional(readOnly=true) 

как он только читает данные. По какой-то причине объем транзакций охватывает все будущие запросы :(Я немного удивлен здесь. Я ожидал бы, что у меня будет транзакция для каждого запроса или нет вообще (транзакция автоматического совершения транзакции).

Я изменил

current_date 

с

date_trunc('day', clock_timestamp()) 

и теперь она прекрасно работает даже через Hibernate.

Я думаю, я должен прочитать больше о Hibernate и JPA 2, или я мог бы столкнуться с подобными проблемами, если я не понимаю область транзакций.

Смежные вопросы