使用Criteria查询进行Hibernate缓存

时间:2015-03-31 18:20:57

标签: java hibernate caching

所以,我的问题是我不确定我的查询是否被缓存。我现在使用的hibernate.xml使用ehcache进行二级缓存。

现在这是我的测试代码:

    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();

HibernateUtil.getCurrentSession()方法检索ThreadLocal变量中的当前会话(如果可用)。如果会话为null,则会创建一个。

HibernateUtil.closeCurrentSession()ThreadLocal变量获取会话,如果它不为空则关闭它。

每当我运行上面的代码(这是一个JUnit测试)时,我只能看到一个从数据库中选择的Hibernate日志。我期待有两个,因为我没有使用Criteria.setCaching(true)强行缓存任何内容。

我认为第一级缓存仅存在于会话范围内,而第二级缓存基本上是应用程序缓存。在上面两个criteria.uniqueResult()调用的中间,我关闭了会话。

我的问题是,为什么我只看到一个Hibernate SELECT语句日志?我不应该看到两个吗?

此外,当我转到我的hibernate.xml并禁用二级缓存时,仍会出现相同的输出,这真的让我很困惑。

我看到的SELECT语句日志示例:`Hibernate:选择this_.id为id8_0_,this_.nameas name8_0_,来自用户this_其中this_.id =?

编辑:这次我尝试了不同的方法。请参阅以下代码段:

@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();

        }
    }
}

所以,现在,每次测试调用Criteria.uniqueResult()时,它都会显示一个Hibernate日志。那么现在,我关心的是我甚至还在缓存任何东西?使用此测试启用了二级缓存(ehcache)。

编辑2:好的,现在,我想到了为什么它不是缓存。事实证明我必须将<cache usage="read-write"/>放在我对象的XML的<class>内。但是,我不能这样做,因为其他应用程序也在使用XML。无论如何只能在您的应用程序上启用缓存吗?

1 个答案:

答案 0 :(得分:0)

您看到一个查询,因为id = 777008的User对象已经在Hibernate上下文中。尝试使用名称字段而不是@Id字段进行查询,您应该看到两个查询。

此外,您可以在配置中全局启用查询缓存,而无需为特定查询设置它。