1

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();
}
mdoust
  • 429
  • 1
  • 4
  • 20

2 Answers2

0

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);
Manjunath
  • 1,685
  • 9
  • 9
  • Thanks. I included the CacheMode.IGNORE (as you can see in the EDIT) but still same problem! – mdoust Aug 09 '14 at 11:27
  • Sorry for delay in response. Your code looks to be correct. Will it be possible to turn on the show_sql property to see the actual query fired in the find method and whether the new message got satisfies the criteria given in find and also log the result of find to make sure it is returning only one record. Sorry for not being able to help out much here. Please do let us know just in case if you found a fix. – Manjunath Aug 10 '14 at 10:07
  • OK, I finally found out what was the problem thanks to your suggestion. Normally Hibernate only writes out the query without values to the terminal. I made some changes to log4j configuration and had the exact sql query pretend out. There was a slight time difference between my system time and SMS provider time and it resulted in query not showing the new message. Thanks for you cooperation. – mdoust Aug 10 '14 at 17:16
0

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.

mdoust
  • 429
  • 1
  • 4
  • 20