1

我正在开发一个连接到外部服务以获取新 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();
}
4

2 回答 2

0

是的,看起来休眠正在缓存您的查询并返回缓存的结果。

请向我们概述您的代码以提供更好的建议。

下面列出了两种控制查询缓存行为的方法:-

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);
于 2014-08-09T07:16:05.497 回答
0

经过多次测试,我发现这个问题根本与缓存无关。在收到每条消息后,我会根据 SMS 面板提供的数据而不是我自己的机器时间来存储到达时间。

这两者之间存在细微的时间差异(准确地说是 20 秒),这是查询未返回新收到的消息的原因。

于 2014-08-10T18:41:00.580 回答