简体   繁体   中英

Elusive Hibernate Second Level Cache

I am very confused with the output of the following code that tries to avoid Hibernate caching.

I open a fresh Hibernate session, run a query, and check the result when it stops at the indicated breakpoint. Before continuing execution, I go to MySQL and delete or add a row. When I continue executing, the query still shows old data and old row count, inspite of the evictAllRegions() call on the hibernate cache, while the plain JDBC query shows the updated count (as expected).

Setting hibernate.cache.use_second_level_cache and hibernate.cache.use_query_cache to false didn't help. I guess it shouldn't matter as the cache is being cleared manually.

So, why is Hibernate not hitting the database?

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

I believe this is a result of having the transaction isolation level set to REAPEATABLE-READ in MySQL.

When you issue the query from your code, MySQL creates a snapshot of the language table that it continues to present for the remainder of that transaction. So the data is effective cached at MySQL rather than at Hibernate.

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

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