问题,Hibernate是否默认启用了SessionFactory级别的二级缓存。
实验代码如下: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 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.   

    1 . 在你这个应用的配置中二级缓存是不存在的,需要配置(ehcache,oscache,...)2 . 至于为什么2个线程中返回的hashcode是一样 有可能session.load(User.class, "1");
    取得的时候是在一级缓存取得的。 
      

  2.   

    User user = (User) session.load(User.class, "1");是在各自的线程中取得数据库中的同一条记录而已。由于缓存和ORM的存在,这条记录被封装成了一个user对象。但是,一级缓存是和Session相关的,而Session是和线程相关的,所以一级缓存是和线程相关的。线程的存储区是私有的,无法相互访问的,处于不同线程中的各个Session的一级缓存应该也是彼此不可见的。所以,即便我在多个线程中load同一个对象,这些对象应该是彼此独立的,而不是同一个。
    在没有明确配置二级缓存的情况下,上述程序的运行结果则表明这些对象是同一个(因为HashCode相同)。所以,我猜测Hibernate是不是默认的开启了二级缓存,所有一级缓存的数据都要先经过二级缓存。
    问题已经困惑了我几天了,弟兄们帮忙顶顶了。
    恳请高手解惑!!!!!!
      

  3.   

    我知道了。我一不小心重写了HashCode生成方法。搞定!