posts - 165, comments - 198, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

hibernate 部分问题总结——1

Posted on 2007-11-12 16:29 G_G 阅读(2056) 评论(3)  编辑  收藏 所属分类: hibernate
缓存问题:
     /**  使用 Query.executeUpdate() 缓存中数据不同步 解决办法
     *  Table -> T1oo(id,name)
     * Table -> T2oo(id,avg,aid)
     * 外键 T1oo.id->T2oo.aid
     *  Session.createQuery("delete T1oo") ->  Query.executeUpdate() 
    
*/
    
public   void  testExecuteUpdate(){
        System.out.println(
" \r\n\r\n********************ExecuteUpdate************************ " );
        T1oo t1oo 
=   new  T1oo();
        t1oo.setName(
" liukaiyi " );
        
        HibernateSessionFactory.closeSession();
        
        Session session 
=  HibernateSessionFactory.currentSession();
    Transaction tr1 
=  session.beginTransaction();
        
// t1 成为 持久状态 一级缓存中 加载
        session.saveOrUpdate(t1oo); 
        
// 直接一条语句删除T1oo,缓存无法同步
        
// 一级缓存中还有 t1
        Query qu  =  session.createQuery( " delete T1oo " );
        
try  {
            qu.executeUpdate();
        } 
catch  (Exception e) {    
            System.out.println(
" //err: 有级联 单使用 delete T1oo 还要delete T2oo.aid = T1oo.id// " );
            List list 
=  session.createQuery( " from T1oo " ).list();
            
for (Iterator it = list.iterator();it.hasNext();){
                Query t2qu 
=  session.createQuery( " delete T2oo  where aid=:id " );
                t2qu.setInteger(
" id " , ((T1oo)it.next()).getId().intValue());
                t2qu.executeUpdate();                
            }
            qu.executeUpdate();
        }
        
        tr1.commit();
        
    Transaction tr2 
=  session.beginTransaction();
        
// 这直接通过一级缓存中加载t2,但DB中以没有此条数据
        t1oo  =  (T1oo)session.load(T1oo. class ,t1oo.getId());
        t1oo.setName(
" google " );
        
try  {
            tr2.commit();    
        } 
catch  (Exception e) {
            System.out.println(
" //err: update(t1oo)->DB 中数据库中没有 t1oo // " );
        }
        

        System.out.println(
"  一级缓存清空前  " +  session.get(T1oo. class ,t1oo.getId()) );
        session.evict(t1oo);
        System.out.println(
"  一级缓存清空后  " +  session.get(T1oo. class ,t1oo.getId()) );
        
        
// 不把t1oo id 为空,否则当在saveOrUpdate时候就会以为是游离态 update了
        t1oo.setId( null );
        
// id=null insert 调用
        session.saveOrUpdate(t1oo);        
        tr2.commit();
        
    Transaction tr3 
=  session.beginTransaction();
        session.delete(t1oo);
        tr3.commit();
        
        session.close();
        HibernateSessionFactory.closeSession();
        
    }
结果是:
********************ExecuteUpdate************************
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.

Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: delete from t1oo
//err: 有级联 单使用 delete T1oo 还要delete T2oo.aid = T1oo.id//
Hibernate: select t1oo0_.id as id, t1oo0_.name as name0_ from t1oo t1oo0_
Hibernate: delete from t2oo where aid=?
Hibernate: delete from t2oo where aid=?
Hibernate: delete from t2oo where aid=?
Hibernate: delete from t1oo
Hibernate: update t1oo set name=? where id=?
//err: update(t1oo)->DB 中数据库中没有 t1oo //
 一级缓存清空前 hbn.bean.T1oo@287
Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=?
 一级缓存清空后 null
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: delete from t1oo where id=?


Get Load 区别 :
 
    /** Get Load 区别 (在commit前要 session.flush())
     * Table -> T1oo(id,name)
     * 1.如果未能发现符合条件的记录,get方法返回null,而load方法会抛出异常
     * 2.Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。
     * 3.load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,
     *             如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。 
     
*/
    
public void testGetLoad() throws Exception {
        System.out.println(
"\r\n\r\n********************Get<>Load************************");
        Session session 
= HibernateSessionFactory.currentSession();
    
//  数据准备
        T1oo t1oo = new T1oo();
        t1oo.setName(
"liu");
    Transaction t1 
= session.beginTransaction();
        session.saveOrUpdate(t1oo);
        
// 为什么这会错?
        
//session.evict(t1oo);
        
//session.flush();
        t1.commit();
        session.evict(t1oo);
    
    Transaction t2 
= session.beginTransaction();
        System.out.println(
"一级缓存是否有t1oo(load)->"+session.contains(t1oo)); 
        
//这时候t1oo为 CGlib生成的代理类
        t1oo = (T1oo)session.load(T1oo.class,t1oo.getId());
        System.out.println(
" 延迟加载出现:select.. t1oo0_.id=? 表的其他属性加载 ");
        t1oo.setName(
"load list");
        
//后在 update
        t2.commit();
        session.evict(t1oo);
        
    Transaction t3 
= session.beginTransaction();
        System.out.println(
"一级缓存是否有t1oo(get)->"+session.contains(t1oo)); 
        
//这时候t1oo为 CGlib生成的代理类
        t1oo = (T1oo)session.get(T1oo.class,t1oo.getId());
        System.out.println(
" 没有延迟加载出现");
        t1oo.setName(
"get list");
        
//后在 update
        t3.commit();    
        session.evict(t1oo);
        
    Transaction tr3 
= session.beginTransaction();
        session.delete(t1oo);
        tr3.commit();
        
        session.close();
        HibernateSessionFactory.closeSession();
        
    }
结果
********************Get<>Load************************
Hibernate: insert into t1oo (name, id) values (?, ?)
一级缓存是否有t1oo(load)->false
 延迟加载出现:select.. t1oo0_.id=? 表的其他属性加载
Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=?
Hibernate: update t1oo set name=? where id=?
一级缓存是否有t1oo(get)->false
Hibernate: select t1oo0_.id as id0_, t1oo0_.name as name0_0_ from t1oo t1oo0_ where t1oo0_.id=?
 没有延迟加载出现
Hibernate: update t1oo set name=? where id=?
Hibernate: select t2ooset0_.aid as aid1_, t2ooset0_.id as id1_, t2ooset0_.id as id0_, t2ooset0_.avg as avg1_0_, t2ooset0_.aid as aid1_0_ from t2oo t2ooset0_ where t2ooset0_.aid=?
Hibernate: delete from t1oo where id=?


Set 集合的识别

    /** Set 集合的识别
     * Table -> T1oo(id,name)
     * Table -> T2oo(id,avg,aid)
     * 外键 T1oo.id->T2oo.aid
     * T1oo  <set name="t2ooSet" inverse="false" cascade = "all"  >
     * T2oo  <many-to-one name="t1oo" column="aid" class="T1oo" />
     * cascade='insert' 是一定要的
     *     当 T1oo没有 inverse="true" 主动权的时候,要双项关联
     *     t1oo.getT2ooSet().add(t2oo1);
     *    t1oo.getT2ooSet().add(t2oo2);
     *    t2oo1.setT1oo(t1oo);
     *    t2oo2.setT1oo(t1oo);
     *  要不后sql为:
     *  Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
     *    Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
     *    +----+-----+------+
     *    | id | avg | aid  |
     *    +----+-----+------+
     *    |  1 |  24 | NULL |
     *    |  2 |  23 | NULL |
     *    +----+-----+------+
     *    当 T1oo有 inverse="false"主动权的时候
     *  t1oo.getT2ooSet().add(t2oo1);
     *    t1oo.getT2ooSet().add(t2oo2);
     *  Sql语句为:
     *  Hibernate: insert into t1oo (name, id) values (?, ?)
     *    Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
     *    Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
     *    Hibernate: update t2oo set aid=? where id=?
     *    Hibernate: update t2oo set aid=? where id=?
     *    |  3 |  24 |   12 |
     *    |  4 |  23 |   12 |
     *    +----+-----+------+
    
*/
    
public void testSet(){
        System.out.println(
"\r\n\r\n********************Set************************");
        T1oo t1oo 
= new T1oo();
        t1oo.setName(
"list");
        
        T2oo t2oo1 
= new T2oo(); t2oo1.setAvg(new Integer(23));
        T2oo t2oo2 
= new T2oo(); t2oo2.setAvg(new Integer(24));
        
        
        Session session 
= HibernateSessionFactory.currentSession();
        Transaction tr1 
= session.beginTransaction();
        session.save(t1oo);
        t1oo 
= (T1oo) session.load(T1oo.class,t1oo.getId());

        t1oo.setT2ooSet(
new HashSet()) ;
        t1oo.getT2ooSet().add(t2oo1);
        t1oo.getT2ooSet().add(t2oo2);
         
        System.out.println( t1oo.getT2ooSet().size()
+"" );        
        tr1.commit();
        
        System.out.println();
        T2oo t2oo3 
= new T2oo(); t2oo3.setAvg(new Integer(25));
        T1oo t1oo2 
= new T1oo(); t1oo2.setName("mz");
        t2oo3.setT1oo(t1oo2);
        
        Transaction tr2 
= session.beginTransaction();
        session.save(t2oo3);
        
try {
            tr2.commit();    
        } 
catch (Exception e) {
            System.out.println(
"//err: 没有主动权 cascade = 'all' 不可以级联save t1oo   //");
        }
        session.close();
        HibernateSessionFactory.closeSession();
    }
   

结果是:
********************Set************************
2
Hibernate: insert into t1oo (name, id) values (?, ?)
Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
Hibernate: insert into t2oo (avg, aid, id) values (?, ?, ?)
Hibernate: update t2oo set aid=? where id=?
Hibernate: update t2oo set aid=? where id=?

//err: 没有主动权 cascade = 'all' 不可以级联save t1oo   //



评论

# re: hibernate 部分问题总结——1  回复  更多评论   

2007-11-19 20:04 by 对象辅导员
不错,收藏

# re: hibernate 部分问题总结——1[未登录]  回复  更多评论   

2009-02-14 11:23 by dd
session.close();
HibernateSessionFactory.closeSession();
为什么要调用两次

# re: hibernate 部分问题总结——1  回复  更多评论   

2009-02-16 09:27 by Skynet
第一次 session.close(); 为本线程的session关闭

HibernateSessionFactory.closeSession(); 第二次为 全部连接断开

只有注册用户登录后才能发表评论。


网站导航: