Hibernate 中 load() 方法导致的 noSession 异常

2021-07-14 20:06

阅读:474

标签:inline   prepare   filter   top   etag   spring   hiberna   add   功能   

之所以要写这个,是因为最近碰到了一个延迟加载的 load() 导致出现 noSession 的异常。

解决这个问题需要用到一个本地线程的对象,也就是 ThreadLocal 类,之前写过关于这个对象,可以看这个博客【本地线程 ThreadLocal 类】

 

      我在数据层中封装了一个 load() 方法,根据用户 Id 获取用户对象:

public UserModel get(Long uuid) {
        return this.getHibernateTemplate().load(UserModel.class, uuid);
        //return this.getHibernateTemplate().get(UserModel.class, uuid);
    }

 

        当在业务层调用了这个方法后,获得一个 userModel 对象,当展示用户信息时,就会报出 noSession 问题,

public String get(){
        //报出了 org.hibernate.LazyInitializationException: could not initialize proxy - no Session异常
        UserModel temp = userEbi.get(1L);
        System.out.println(temp.getName());
        System.out.println(temp.getAge());
        return "haha";
    }

报出的异常如下:

技术分享

 

      这是因为数据层提供的 load() 方法具有延迟加载的特性,也就是获得对象只有 OID ,其他的信息都没有,只有当需要的时候才会去查询(这叫二次查询,延迟加载其他数据),如果二次查询之前,这个只具有 OID 的对象传递到了业务层(如果在事务关闭session之前立马进行二次查询,就不会出问题),此时对象仍是一个延迟加载对象(只具有 OID),如果传递到了表现层(action内),此时该对象依然是延迟加载对象(但此时早在业务层,事务就已经将session关闭了,一旦要进行二次查询就会报异常,因为session对象已经被刷新了,也就是连接断开了,session中存储的数据早已丢失)。

  但是在表现层使用二次查询是比较正常的,也就是要做到当前session不关闭,直到一次请求完成才关闭。这时用到的一个技术就是 openSessionInView

这需要在 web.xml 中配置一个过滤器,用于将每个请求对象 request 和 session 对象绑定在一起(这里的session是与数据库交互的session,并不是浏览器的session会话),至于session的关闭,在一次请求结束时 session 会被自动关闭,这时注解的事务的任务就是开启事务,刷新事务;关闭事物的功能交给了 OpenSessionInViewFilter 这个类了,因为这个过滤器配置在一个,请求对象 request 最先接触到它,请求结束时的最后一个过滤器也是它(这就是过滤器链了,往返要都过滤一次)。代码在下面:(一定要将 OpenSessionInViewFilter 配置在所有过滤器的前面)

xml version="1.0" encoding="UTF-8"?>
web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    
    listener>
        listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
    listener>
    context-param>
        param-name>contextConfigLocationparam-name>
        param-value>classpath:applicationContext.xmlparam-value>
    context-param>
    
    
    filter>
        filter-name>openSessionInViewfilter-name>
        filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilterfilter-class>
    filter>
    filter-mapping>
        filter-name>openSessionInViewfilter-name>
        url-pattern>/*url-pattern>
    filter-mapping>

    
    filter>
        filter-name>struts2filter-name>
        filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class>
    filter>

    filter-mapping>
        filter-name>struts2filter-name>
        url-pattern>/*url-pattern>
    filter-mapping>

web-app>

Hibernate 中 load() 方法导致的 noSession 异常

标签:inline   prepare   filter   top   etag   spring   hiberna   add   功能   

原文地址:http://www.cnblogs.com/daimajun/p/7074613.html


评论


亲,登录后才可以留言!