日期:2014-05-19  浏览次数:20705 次

Hibernate的二级缓存问题
问题,Hibernate是否默认启用了SessionFactory级别的二级缓存。
实验代码如下:
Java code

package hibernatetest;

import packages
public class CacheTest {

    public static void main(String[] args) throws Exception {

        Configuration conf = new Configuration();
        conf.addClass(User.class);
        SessionFactory sf = conf.configure().buildSessionFactory();

        Thread t1 = new Thread(new UserThread(sf));
        Thread t2 = new Thread(new UserThread(sf));
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        sf.close();

    }

}

class UserThread implements Runnable {

    SessionFactory sf;

    public UserThread(SessionFactory sf) {
        this.sf = sf;
    }

    public void run() {
        Session session = sf.openSession();
        System.out.println(Thread.currentThread().getName() + " "
                + session.hashCode());
        Transaction tx = session.beginTransaction();
        User user = (User) session.load(User.class, "1");
        System.out.println(Thread.currentThread().getName() + " "
                + user.hashCode());
        tx.commit();
        session.close();

    }
}


Hibernate配置文件如下:
XML code

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

    <session-factory>
        <property name="myeclipse.connection.profile">
            oracleDriver
        </property>
        <property name="connection.url">
            jdbc:oracle:thin:@localhost:1521:master
        </property>
        <property name="connection.username">xxxxx</property>
        <property name="connection.password">xxxxx</property>
        <property name="connection.driver_class">
            oracle.jdbc.driver.OracleDriver
        </property>
        <property name="dialect">
            org.hibernate.dialect.Oracle10gDialect
        </property>
    </session-factory>

</hibernate-configuration>


自己在做测试之前的想法是:Hibernate的二级缓存是必须经过明确配置才能启用的。也就是说上述两个线程输出的User的hashCode应该是不一样的。但是运行结果如下:
Thread-0 1352077
Thread-1 8012937
Thread-0 -175096011
Thread-1 -175096011
很明显,这两个线程当中的session是不一样的。但是后取数据的那个线程似乎是从二级缓存当中取得数据,否则两个User的hashCode值不可能一样。
Hibernate似乎自动启用了Application级别的二级缓存。那么像webapp这样的应用中,一个Object自动被载入了Hibernate二级缓存,在没有被清理之前,它是否也一直存在——个人感觉这点对长对话的处理很有影响。
请高手解惑!
十分感谢!


------解决方案--------------------


1 . 在你这个应用的配置中二级缓存是不存在的,需要配置(ehcache,oscache,...)

2 . 至于为什么2个线程中返回的hashcode是一样 有可能session.load(User.class, "1");
取得的时候是在一级缓存取得的。