Hibernate在更改数据时缓存查询

时间:2014-08-09 02:43:57

标签: java spring hibernate caching hibernate-cache

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

2 个答案:

答案 0 :(得分:0)

是的,看起来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);

答案 1 :(得分:0)

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

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