Я разрабатываю приложение, которое подключается к внешней службе для получения нового SMS. Сообщения тезисов хранятся в локальной базе данных с помощью Hibernate. Мой клиент может искать эти сообщения на основе многочисленных параметров, таких как время, число и т.д.
После вызова метода поиска со списком параметров, называемых "List1", я получаю желаемый результат без каких-либо проблем. Хотя пока я жду этого результата, появилось новое сообщение.
Вскоре после этого я снова вызываю метод поиска с тем же списком параметров, и я ожидаю получить новое сообщение, но я получаю предыдущий результат.
Я проверил мою базу данных, и появилось новое сообщение, поэтому все, что я могу придумать, - это кэширование Hibernate. Поскольку оба запроса одинаковы, я думаю, что hibernate возвращает тот же набор результатов, что и раньше.
В случае, если мое предположение верно, как я могу решить эту проблему? Если нет, то что именно происходит?
редактировать
вот важная часть моего исходного кода. Следующие два метода будут вызываться, когда клиент инициирует запрос на поиск:
smsService.refresh();
JSONArray result = smsService.retrieveMessages(...);
@Transactional
public JSONArray retrieveMessages(Long periodBegining, Long periodEnd, String order, Integer limit, String profile, Boolean unread, String correspondent) {
List<ShortMessage> messageList = shortMessageDAO.find(beginDate, endDate, order, limit, profile, unread, correspondent);
JSONArray result = new JSONArray();
for (ShortMessage message : messageList)
result.put(message.toJSON());
shortMessageDAO.markRead(messageList);
return result;
}
@Transactional
public void refresh() {
webService.authentication(serviceUsername, servicePassword);
while(webService.hasUnread() > 0) {
SMS sms = webService.retrieveMessage();
ShortMessage message = new ShortMessage(sms.getHash(), sms.getFrom(), sms.getTo(), "DEFAULT", sms.getMessage(), new Date(sms.getTime()), true);
shortMessageDAO.insert(message);
}
}
}
public List<ShortMessage> find(Date beginDate, Date endDate, String order, Integer limit, String profile, Boolean unread, String correspondent) {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ShortMessage.class);
criteria.add(Restrictions.ge("time", beginDate));
criteria.add(Restrictions.le("time", endDate));
criteria.add(Restrictions.eq("profile", profile));
if (unread)
criteria.add(Restrictions.eq("unread", true));
if (correspondent != null)
criteria.add(Restrictions.eq("origin", correspondent));
criteria.addOrder(order.equals("ASC") ? Order.asc("time") : Order.desc("time"));
criteria.setMaxResults(limit);
criteria.setCacheMode(CacheMode.IGNORE);
return (ArrayList<ShortMessage>) criteria.list();
}
После выполнения многочисленных тестов я выяснил, что эта проблема вообще не связана с кешем. После получения каждого сообщения я бы сохранил время прибытия на основе данных, предоставленных панелью SMS, а не моего собственного машинного времени.
Была небольшая разница во времени (точнее, 20 секунд) между теми 2, которые были причиной запроса, не возвращающего новое полученное сообщение.
Да, похоже, что hibernate кэширует ваш запрос и возвращает результаты кэширования.
Пожалуйста, дайте нам обзор вашего кода, чтобы предложить лучше.
Ниже перечислены два способа контроля поведения кеширования запросов:
1) На основном заданном уровне запросов: -
@NamedQuery(
name = "myNamedQuery"
query = "SELECT u FROM USER WHERE u.items is EMPTY"
hints = {@QueryHint(name = "org.hibernate.cacheMode", value = "IGNORE")}
)
2) На уровне отдельных запросов: -
Query q = session.createQuery("from User")
.setCacheMode(CacheMode.IGNORE);