Hibernate caches the query while data is being changed

1.4k Views Asked by At

I'm developing an application which connects to an outside service to fetch new SMS. Theses messages are stored in a local database by Hibernate. My client can search these messages based on numerous parameters such as time, number, and etc.

After calling the search method with a list of parameters called 'List1', I get the desired result without any problems. Though while I'm waiting for this result a new message has arrived.

Soon after, I call the search method with same parameter list again and I'm expecting to get the new message as well, but I get the previous result.

I have checked my database and the new message is present so all I can think of is Hibernate caching. Since both queries are exactly the same, I guess hibernate return the same result set as before.

In case my assumption is correct, how can I overcome this problem? If not, so what exactly is going on?


Edit

here is relevant part of my source code. Following two methods will be invoked when client initiates a search request:

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

There are 2 best solutions below

0
On BEST ANSWER

After running numerous test, I found out that this problem is not cache related at all. Upon receiving each message I would have stored the time of arrival based on data provided by SMS panel and not my own machine time.

There was a slight time difference (20 seconds to be exact) between those 2 which was the reason behind the query not returning the new received message.

3
On

Yes it looks like hibernate is caching your query and returning cached results.

Please give us a overview of your code to suggest better.

Below listed are two ways of controlling the caching behaviour of queries:-

1) At the main named query level:-

@NamedQuery(
    name = "myNamedQuery"
    query = "SELECT u FROM USER WHERE u.items is EMPTY"
    hints = {@QueryHint(name = "org.hibernate.cacheMode", value = "IGNORE")}
)

2) At individual query level :-

Query q = session.createQuery("from User")
.setCacheMode(CacheMode.IGNORE);