• 十三、hibernate对象的三种状态与懒加载机制


    一、对象状态简介

    1.瞬时态(transient):数据库中没有数据与之对应,超过作用域会被JVM回收,一般是new出来的且与session没有关联的对象

    2.持久态(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交.(持久态对象状态发生改变,在事务提交时会影响到数据库)

    3.脱管态/游离态(detached):数据库中有数据与之对应,但当前没有session与之关联,脱管对象状态发生改变,hibernate不能检测到。

     

    Course c1=new Course();//瞬时态
    
    c1.setCname("PHP");//瞬时态
    
    c1.setCcredit(3);//瞬时态
    
    c1.setCid(19);//瞬时态
    
     
    
    Session session=HibernateUtil.getCurrentSession();
    
    Transaction ts=null;
    
    try {
    
    session=HibernateUtil.getCurrentSession();
    
    ts=session.beginTransaction();
    
     
    
    session.save(c1);//持久态,此时c1处于session管理之下
    
    c1.setCname("python");//持久态的对象状态发生改变,hibernate会检测到,并且会同步到数据库中
    
    ts.commit();
    
     
    
    c1.setCcredit(5);//ts已经提交,此时处于游离态,状态改变hibernate检测不到,也不会同步到数据库中
    
    } catch (Exception e) {
    
    // TODO: handle exception
    
    e.printStackTrace();
    
    if(ts!=null) ts.rollback();
    
    }finally{
    
    if(session!=null&&session.isOpen()){//事务提交或者关闭session都会使对象处于游离态
    
    session.close();
    
    }
    
    }

     

    二、hibernate对象状态图

     

     

     

    三、懒加载机制

     

    默认情况下,xxx.hbm.xml<class lazy=”true”>,即启用了懒加载机制。

     

    以下情况应注意懒加载机制:

     

    load方法

    Load先到缓存(session缓存/二级缓存)中去查,如果没有则返回一个代理对象(不马上到DB中去找,即不发出sql语句),等后面使用这个代理对象操作的时候,才到DB中查询(发出SQL语句),这就是我们常说的load在默认情况下支持延迟加载(lazy),如果禁用了懒加载机制,则命令Load先到缓存(session缓存/二级缓存)中去查,如果没有则立即发出SQL语句到数据库中查询。

    session外得到对象属性

    Employee e=(Employee) session.get(Employee.class, 1);
    
    System.out.println(e.getName()+e.getDept().getName());

     

    以上代码在session中执行并不会出错,但是如果我是将e返回给上一级,在别的地方处理e,例如在session外打印e.getDept().getName(),则会报错could not initialize proxy - no Session不能初始化代理对象,没有session。其实在sessione.getName()不会报错,因为这是它本身的属性,而e.getDept().getName()需要session再发出sql语句去查,所以在session已经关闭的情况下就报错了。

     

    这个异常有两种处理方式,

    一是Department.hbm.xml<class lazy=”false”>,关闭懒加载。

    二是在得到e之后就强制session去发出sql得到e.getDept(),并绑定在e身上,此时e.getDept()也相当于是e的自身的属性了。

    具体代码:

    e=(Employee) session.get(Employee.class, 1);
    
    Hibernate.initialize(e.getDept());//发出sql语句得到dept所有属性

     

  • 相关阅读:
    javascript:void(0) 真正含义
    Memcache and Mongodb
    window下redis nosql初试
    CAS单点登录配置
    代理模式-你不并知道我的存在
    Netty In Action中文版
    【FastDev4Android框架开发】打造QQ6.X最新版本号側滑界面效果(三十八)
    同步并发操作之等待一次性事件
    关于Java特种兵下冊
    自己定义UISlider的样式和滑块
  • 原文地址:https://www.cnblogs.com/myz666/p/8425129.html
Copyright © 2020-2023  润新知