zoukankan      html  css  js  c++  java
  • Hibernate 延迟加载原理

        如何简单的理解延迟加载?开发中常见的org.hibernate.LazyInitializationException no session错误又是怎么产生的?下面通过一个简单的例子来解析一下。

    load VS. get

        load是Hibernate利用延迟加载获取对象的方法,当调用load时返回的是一个代理对象,并且该对象只包含主键ID。只有当你想主动获取该对象的其他非主键属性时,才会去数据库中获取对应的属性返回。如果这时该对象对应的数据库记录被删除了或不存在则会报抛出ObjectNotFoundException异常。

        get是Hibernate获取对象的一个普通方法,没有使用延迟加载,调用get时hibernate直接返回数据库中对应的记录信息。如果数据库中不存在该对象的记录,会抛出空指针异常。

    程序所示

    load:

       1:  Session session = null;
       2:          try {
       3:              session = HibernateUtil.openSession();
       4:              //使用load,利用延迟加载获取对象其他属性
       5:              Object object = session.load(Member.class, 121L);
       6:              String mobile = ((Member) object).getMobile();//<---这里当调用getMobile()时,才会去数据库查询对应的记录
       7:              System.out.println(mobile);
       8:          } catch (HibernateException e) {
       9:              e.printStackTrace();
      10:          } finally {
      11:              if (session != null)
      12:                  session.close();
      13:          }

    get:

       1:  Session session = null;
       2:          try {
       3:              session = HibernateUtil.openSession();
       4:              //使用get,直接从数据库中查询对应的记录
       5:              Object object = session.get(Member.class, 121L);
       6:              String mobile = ((Member) object).getMobile();//<---这里没有使用延迟加载直接获取mobile
       7:              System.out.println(mobile);
       8:          } catch (HibernateException e) {
       9:              e.printStackTrace();
      10:          } finally {
      11:              if (session != null)
      12:                  session.close();
      13:          }

    使用延迟加载时,常见的org.hibernate.LazyInitializationException no session异常,又是怎么产生的呢?

    这是因为当使用延迟加载获取对象属性时如果这时session已经关闭,则无法进行数据库操作,就会报出上述异常,我们用程序模拟一下:

    get:

       1:  Session session = null;
       2:          try {
       3:              session = HibernateUtil.openSession();
       4:              //使用get,直接从数据库中查询对应的记录
       5:              Object object = session.get(Member.class, 121L);
       6:              session.close();//这时关闭session
       7:              String mobile = ((Member) object).getMobile();//可以正常获取,因为mobile是从对象中直接获取的
       8:              System.out.println(mobile);
       9:          } catch (HibernateException e) {
      10:              e.printStackTrace();
      11:          } 

    load:

       1:  Session session = null;
       2:          try {
       3:              session = HibernateUtil.openSession();
       4:              //使用get,直接从数据库中查询对应的记录
       5:              Object object = session.load(Member.class, 121L);
       6:              session.close();//这时关闭session
       7:              String mobile = ((Member) object).getMobile();//使用load的情况,获取mobile是从数据库中查询的,但此时session已经关闭,故调用getMobile时会抛出org.hibernate.LazyInitializationException no session异常
       8:              System.out.println(mobile);
       9:          } catch (HibernateException e) {
      10:              e.printStackTrace();
      11:          } 
  • 相关阅读:
    Redis的高可用详解:Redis哨兵、复制、集群的设计原理,以及区别
    高并发架构系列:Redis为什么是单线程、及高并发快的3大原因详解
    Docker安装Zookeeper并进行操作
    org.yaml.snakeyaml.error.YAMLException: java.nio.charset.MalformedInputException: Input length = 1
    SpringBoot启动加载yml配置文件出现编码格式错误
    log4j:WARN No appenders could be found for logger ().解决方案
    SpringBoot&Dubbo&Zookeeper远程调用项目搭建
    Postman下载与安装
    echart 饼图图例legend支持滑动
    web app 开发必不可少的滑动插件 Flipsnap
  • 原文地址:https://www.cnblogs.com/leefreeman/p/3289374.html
Copyright © 2011-2022 走看看