简体   繁体   中英

Hibernate caching using Criteria queries

So, my problem is I'm not sure whether my queries are being cached. The hibernate.xml that I have right now uses ehcache for the second level cache.

Right now this is my test code:

    Session session = HibernateUtil.getCurrentSession();
    Criteria criteria = session.createCriteria(Users.class);
    criteria.add(Restrictions.eq("id", "777008"));

    Users user = (Users) criteria.uniqueResult();

    HibernateUtil.closeCurrentSession();

    Session anotherSession = HibernateUtil.getCurrentSession();
    Criteria anotherCriteria = anotherSession.createCriteria(Users.class);
    anotherCriteria.add(Restrictions.eq("id", "777008"));

    Users anotherUser = (Users) anotherCriteria.uniqueResult();

The HibernateUtil.getCurrentSession() method retrieves the current session in a ThreadLocal variable if it's available. If the session is null, then it creates one.

The HibernateUtil.closeCurrentSession() gets the session from the ThreadLocal variable and closes it if it's not null.

Whenever I run the code above (it's a JUnit test), I can only see one Hibernate log that SELECTS from the database. I was expecting there to be two since I'm not forcefully caching anything by using Criteria.setCaching(true) .

I believe that first level caches only exist within the session scope and second level caches are basically application caches. In the middle of the two criteria.uniqueResult() invocations above, I close the session.

My question is, why am I only seeing one Hibernate SELECT statement log? Shouldn't I be seeing two?

Also, when I go to my hibernate.xml and disable second level caching, the same output still appears which is what really confuses me alot.

Example of SELECT statement log that I see: `Hibernate: select this_.id as id8_0_, this_.nameas name8_0_, from users this_ where this_.id=?

EDIT: I tried a different approach this time. Please refer to the following code snippet below:

@Test
public void testCaching(){

    for (int i = 0; i < 10; i++){


        try {
            Thread.sleep(3000);

            logger.info("Retrieving user.");
            Session session = HibernateUtil.getCurrentSession();
            Criteria criteria = session.createCriteria(Users.class);
            criteria.add(Restrictions.eq("id", "777008"));
            criteria.setCacheable(true); 

            Users user = (Users) criteria.uniqueResult();

        }
        catch (Exception ex){
            System.out.println("Got it");
        }
        finally{
            HibernateUtil.closeCurrentSession();

        }
    }
}

So, now, every time the test invokes Criteria.uniqueResult() , it displays a Hibernate log. So now, what I'm concerned about is am I even caching anything? Second-level caching (ehcache) is enabled using this test.

EDIT 2: Okay so now, I sort of figured why it wasn't caching. Turns out that I had to put <cache usage="read-write"/> inside the <class> of my object's XML. However, I can't do that since other applications are using the XML as well. Is there anyway to enable caching only on your application?

You see one query because the User object of id=777008 is already in the Hibernate context. Try to query using name field instead of @Id field and you should see two queries.

Also query caching can be already switched on globally in your cofiguration without you setting it on for the particular query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM