难以捉摸的Hibernate二级缓存

时间:2014-07-22 14:23:29

标签: java hibernate

我对以下代码的输出感到困惑,这些代码试图避免Hibernate缓存。

我打开一个全新的Hibernate会话,运行查询,并在指定的断点处停止时检查结果。在继续执行之前,我转到MySQL并删除或添加一行。当我继续执行时,查询仍会显示旧数据和旧行计数,尽管对hibernate缓存进行evictAllRegions()调用,而普通JDBC查询显示更新计数(如预期)。

hibernate.cache.use_second_level_cache hibernate.cache.use_query_cache 设置为false没有帮助。我想这应该无关紧要,因为手动清除缓存。

那么,为什么Hibernate没有访问数据库呢?

Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb...");

for (int i = 0; i < 15; i++) {
    session = HibernateUtil.getSessionFactory().openSession();

    // Old data keeps being returned
    list = session.createCriteria(Language.class).list();

    // JDBC fetches expected count
    Statement statement = conn.createStatement();
    ResultSet resultSet = statement.executeQuery("select * from language");
    int x = 0;
    while (resultSet.next()) x++; // count the rows

[Breakpoint here]
    session.close();
    HibernateUtil.getSessionFactory().getCache().evictAllRegions();
}

1 个答案:

答案 0 :(得分:0)

我相信这是在MySQL中将事务隔离级别设置为REAPEATABLE-READ的结果。

当您从代码中发出查询时,MySQL会创建语言表的快照,并在该事务的剩余部分中继续显示该快照。所以数据在MySQL而不是Hibernate上有效缓存。

http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read