首先我在已启用EhCache 缓存插件 ,并且对于下列领域模型都配置了二级缓存,包括VO的相关联类
请看下列代码:
Session session = HibernateUtils.getSession();
Session session2 = HibernateUtils.getSession();
try{
         //这里将到数据库中查找Tcustomer的所有ID  
Iterator<Tcustomer> cus =session.createQuery("from Tcustomer").iterate();
        //通过ID查找实体类
Tcustomer cusss = cus.next();
        System.out.println(cusss.getName()+" "+cusss.getLocation(0).getAddress());
         
        //这里将继续发出SQL语句 因为存在不同session 1级缓存查找不到 也并没有在二级缓存中找到 
        Tcustomer cus2 =(Tcustomer)session2.load(Tcustomer.class, "402805b82597060f0125970613c90001");
System.out.println(cus2.getName()+" "+cus2.getLocation(0).getAddress());
  
}catch(Exception e){
e.printStackTrace();
}
finally{
HibernateUtils.closeSession(session);
HibernateUtils.closeSession(session2);
}控制台输出:Hibernate: select tcustomer0_.id as col_0_0_ from t_customer tcustomer0_
Hibernate: select tcustomer0_.id as id0_0_, tcustomer0_.name as name0_0_ from t_customer tcustomer0_ where tcustomer0_.id=?
Hibernate: select locations0_.customer_id as customer3_1_, locations0_.id as id1_, locations0_.id as id1_0_, locations0_.address as address1_0_, locations0_.customer_id as customer3_1_0_ from t_location locations0_ where locations0_.customer_id=? order by locations0_.id
ttttttttt bb
Hibernate: select tcustomer0_.id as id0_0_, tcustomer0_.name as name0_0_ from t_customer tcustomer0_ where tcustomer0_.id=?
Hibernate: select locations0_.customer_id as customer3_1_, locations0_.id as id1_, locations0_.id as id1_0_, locations0_.address as address1_0_, locations0_.customer_id as customer3_1_0_ from t_location locations0_ where locations0_.customer_id=? order by locations0_.id
ttttttttt bb
再看下列代码:Session session = HibernateUtils.getSession();try{
Iterator<Tcustomer> cus =session.createQuery("from Tcustomer").iterate();
Tcustomer cusss = cus.next();
System.out.println(cusss.getName()+" "+cusss.getLocation(0).getAddress());
}catch(Exception e){
e.printStackTrace();
}
finally{
HibernateUtils.closeSession(session);
}
Session session2 = HibernateUtils.getSession();
try{
//这里并没有发出SQL语句 说明利用了缓存 这是为何?
Tcustomer cus2 =(Tcustomer)session2.load(Tcustomer.class, "402805b82597060f0125970613c90001");
System.out.println(cus2.getName()+" "+cus2.getLocation(0).getAddress());
}catch(Exception e){
e.printStackTrace();
}
finally{

HibernateUtils.closeSession(session2);
}
}
控制台输出:Hibernate: select tcustomer0_.id as col_0_0_ from t_customer tcustomer0_
Hibernate: select tcustomer0_.id as id0_0_, tcustomer0_.name as name0_0_ 
           from t_customer tcustomer0_ where tcustomer0_.id=?
Hibernate: select locations0_.customer_id as customer3_1_, locations0_.id as id1_, locations0_.id as id1_0_, locations0_.address as address1_0_, locations0_.customer_id as customer3_1_0_ from t_location locations0_ where locations0_.customer_id=? order by locations0_.id
ttttttttt bb
ttttttttt bb为什么在获取session的位置不同 而产生这么的差别呢 内部细节究竟如何? 
PS:如何分数不够 可以在加

解决方案 »

  1.   

    参考一下这里
    http://www.javaeye.com/topic/249465
      

  2.   

    自己顶一个 并欢迎大家加入JAVA高级研讨Q群 87114209
      

  3.   

    可能的原因是:只有关闭session时数据才会被放到2级缓存里。如果想知道2级缓存里到底有什么,可以用下列代码:Map cacheEntries = sessionFactory.getStatistics()
            .getSecondLevelCacheStatistics(regionName) //这里regionName就是class name
            .getEntries();要开启Hibernate的统计功能:hibernate.generate_statistics true
    hibernate.cache.use_structured_entries true
      

  4.   

    看看这个
    http://www.javaeye.com/topic/18904
      

  5.   

    楼主上面的列子和二级缓存没关系,而是一级缓存的问题。Session session = HibernateUtils.getSession();
    Session session2 = HibernateUtils.getSession();
    这里同时开启二不同的session。     //这里将到数据库中查找Tcustomer的所有ID  
        Iterator<Tcustomer> cus =session.createQuery("from Tcustomer").iterate();
            //通过ID查找实体类
        Tcustomer cusss = cus.next();
            System.out.println(cusss.getName()+" "+cusss.getLocation(0).getAddress());
             
            //这里将继续发出SQL语句 因为存在不同session 1级缓存查找不到 也并没有在二级缓存中找到 
            Tcustomer cus2 =(Tcustomer)session2.load(Tcustomer.class, "402805b82597060f0125970613c90001");
        System.out.println(cus2.getName()+" "+cus2.getLocation(0).getAddress());这里对于cus 仅存在于session中,所以session2中根本找不到Tcustomer 对象,必然直接从数据库里面查找。
      

  6.   

    参考下
    http://nintenyun.javaeye.com/blog/510446
      

  7.   

    你这不是二级缓存吧。。//这里并没有发出SQL语句 说明利用了缓存 这是为何?
        Tcustomer cus2 =(Tcustomer)session2.load(Tcustomer.class, "402805b82597060f0125970613c90001");
        这个应该是lazy原因。。
      

  8.   

    问题是 session1已经关闭了 他何来一级缓存
    明显是使用了二级缓存
      

  9.   

    在你的程序里加入以下方法//参数为实体配置文件中的配置如下
    //<cache usage="read-write" region="test" include="all" /> 
    //该方法检测是否采用了二级缓存
    protected void test(String name){
    Map<Object, Object> map=HibernateSessionFactory.getSessionFactory().getStatistics()
                                .getSecondLevelCacheStatistics(name).getEntries();
    if(map==null){
    System.out.println("没有采用缓存了......");
    return;
    }
    System.out.println("采用缓存了......");
    System.out.println("开始遍历值");
    for (Object object: map.values()){
    System.out.println(object);
    }
    }
       //调用test("test");
      

  10.   

    Session session = HibernateUtils.getSession();
    Session session2 = HibernateUtils.getSession();
    try{
             //这里将到数据库中查找Tcustomer的所有ID  
        Iterator<Tcustomer> cus =session.createQuery("from Tcustomer").iterate();
            //通过ID查找实体类
        Tcustomer cusss = cus.next();
            System.out.println(cusss.getName()+" "+cusss.getLocation(0).getAddress());
             
            //这里将继续发出SQL语句 因为存在不同session 1级缓存查找不到 也并没有在二级缓存中找到 
            Tcustomer cus2 =(Tcustomer)session2.load(Tcustomer.class, "402805b82597060f0125970613c90001");
        System.out.println(cus2.getName()+" "+cus2.getLocation(0).getAddress());
      
    }catch(Exception e){
        e.printStackTrace();
    }
    finally{
        HibernateUtils.closeSession(session);
        HibernateUtils.closeSession(session2);            
    }以上红色部分标出的是第二次检索,二级缓存已经有数据,为什么还要查询数据库?
      

  11.   

    怎么没有红色
    复制出来:
    注意:见实例一种的 Tcustomer cus2 =(Tcustomer)session2.load(Tcustomer.class, "402805b82597060f0125970613c90001");
       System.out.println(cus2.getName()+" "+cus2.getLocation(0).getAddress());
      

  12.   

    <dl class='code'>qqq</dl>
      

  13.   


    Tcustomer cus2 =(Tcustomer)session2.load(Tcustomer.class, "402805b82597060f0125970613c90001");//这一句有SQL语句吗?
       System.out.println(cus2.getName()+" "+cus2.getLocation(0).getAddress());
                           //这一句肯定要查数据库的...因为load方法加载的是代理对象.....