发现一个问题,我们在同个session里面,把一条语句get出来,它会把对象放进一级缓存和二级缓存,但我在同个session再get一条同样的记录出来时,它只会去一级缓存找,找不到的话不会去二级缓存找了,这是为什么,如果从开个session的话,就会去二级缓存找,比如
s = HibernateSessionFactory.getSession();
user = (User) s.get(User.class, 1);
System.out.println("Put=" + st.getSecondLevelCachePutCount());
s.evict(user);
user = (User) s.get(User.class, 1);
这样会产生2条查询语句,但是执行完第一条是时候我做了个输出,发现已经是把第一条的记录放进了2级缓存的,
s.evict(user);只是把一级缓存清除了,并没有清除二级缓存,为什么第2条语句还是查数据库,
如果多开个session查就会去找 二级缓存,这是为什么啊

解决方案 »

  1.   

    补充个问题,在对query缓存的时候,我在hibernate.cfg.xml中设置
    <property name="generate_statistics">true</property>
    然后在代码中
    q.setCacheable(true);
    结果我发现q.setCacheable(true);
    好像是没有什么用的,因为就算把注释掉或改成flase,都会存入2级缓存,
    只有把xml文件的设置去掉或改成flase才不会存入2级缓存,这样看的话

    q.setCacheable(true);
    还有什么用啊
      

  2.   

    hibernate 的乐观锁,救命
    XML配置文件:
    <version name="version"></version><!-- 乐观锁配置 -->
    类中定义了version
    private int version;//乐观锁版本号public int getVersion() {
    return version;
    }
    public void setVersion(int version) {
    this.version = version;
    }下面是运行代码:
    Session s1 = null;
    Session s2 = null;
    Transaction tx1 = null;
    Transaction tx2 = null;
    try {
    s1 = HibernateSessionFactory.getSessionFactory().openSession();
    tx1 = s1.beginTransaction();
    User user1 = (User) s1.get(User.class, id);


    s2=HibernateSessionFactory.getSessionFactory().openSession();
    tx2 = s2.beginTransaction();
    User user2 = (User) s2.get(User.class, id);
    user1.setFirstName("aaaaaaaaa");
    user2.setFirstName("bbbbbbbbbbbb");
                                tx1.commit();
    tx2.commit();

    }catch(HibernateException e){

    if (tx1!=null) {
    tx1.rollback();
    }
    if (tx2!=null) {
    tx2.rollback();
    }

    }finally{ if (s1 != null) {
    s1.close();
    }
    if (s2 != null) {
    s2.close();
    }
    }
    }按道理来说应该发生错误,但是没发生,编译通过,大侠们救命
      

  3.   

    用load试下,
    load才会使用二级缓存,而get则不使用
      

  4.   

    还有个问题
    s1 = HibernateSessionFactory.getSessionFactory().openSession();
    tx1 = s1.beginTransaction();User user1 = (User) s1.get(User.class, id);
    user1.getName().setFirstName("222222");

    System.out.println("hit=" + st.getSecondLevelCacheHitCount());
    System.out.println("Miss=" + st.getSecondLevelCacheMissCount());
    System.out.println("Put=" + st.getSecondLevelCachePutCount());

    s2 = HibernateSessionFactory.getSessionFactory().openSession();//第一

    tx1.commit();

    User user2 = (User) s2.get(User.class, id);  //第二
    System.out.print(user2.getName().getFirstName());System.out.println("hit=" + st.getSecondLevelCacheHitCount());
    System.out.println("Miss=" + st.getSecondLevelCacheMissCount());
    System.out.println("Put=" + st.getSecondLevelCachePutCount());上面的代码大家帮我分析下,如果是这样写的,“第二”行的代码会去2级缓存拿数据,如果把“第一”的代码拉到“第二”行的前面,就不会去2级缓存拿数据了,而是直接去数据库拿,为什么会这样,我知道嵌套session不好,但是我在模拟乐观锁问题,希望各位大侠帮帮忙解释下
      

  5.   

    从前我以为缓存是额外需要学的东西,后来发现缓存,延迟加载,事务也是hibernate的精髓所在
      

  6.   

    怎么解决我还搞不定。 不过我建议楼主去看看
    3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。 http://baike.baidu.com/view/2273788.htm
      

  7.   

    同一个Session对应的是一级缓存。
    而二级缓存对应的SessionFactory里面。
    你重新起一个Session当时是去二级缓存里找啊。原来那个Session都关闭了,一级缓存也就没有了。
    但是你的SessionFactory还是所以放到二级缓存里的东西还在。