zoukankan      html  css  js  c++  java
  • 十三、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所有属性

     

  • 相关阅读:
    开源协议
    markdown 语法和工具
    mac 终端 使用ftp命令
    谷歌囧大了!安统镜卓5.0刷入遇到system.img系像找不到
    linux下vi命令大全
    python编码处理:unicode字节串转成中文 各种字符串举例说明
    优秀前端资源备忘录
    mousewheel滚轮事件
    bootstrap插件之Carousel
    初识Node.js
  • 原文地址:https://www.cnblogs.com/myz666/p/8425129.html
Copyright © 2011-2022 走看看