hibernate的延迟加载及其与session关闭的矛盾

延迟加载就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载。

那么Hibernate是怎么知道用户在什么时候使用数据了呢?又是如何加载数据呢?

其实很简单,它使用了代理机制。返回给用户的并不是实体本身,而是实体对象的代理。代理对象在用户调用getter方法时就会去数据库加载数据。

但加载数据就需要数据库连接。而当我们把会话关闭时,数据库连接就同时关闭了。这种情况就叫做未初始化的关系。

延迟加载与session关闭的矛盾一般可以这样处理:

1)、关闭延迟加载特性。     操作起来比较简单,因为hibernate的延迟加载特性是在hbm配置里面可控制的。默认lazy="true",改为lazy="false"就可以了。     但是使用这个解决办法带来的隐患是十分大的。     首先,出现no session or session was closed就证明了您已经在使用外键关联表,如果去掉延迟加载的话,则表示每次查询的开销都会变得十分的大,如果关联表越多,后果也可以想象得到。所以不建议使用这个方法解决。

2)、在session关闭之前把我们想要查询的数据先获取了。 首先需要了解一下session什么时候关闭,也就是它的生命周期。通常情况下hibernate会在查询数据关闭session,而使用getHibernateTemplate().get方法查询后会延迟关闭的时间。会在事务结束后才关闭。     使用拦截器(Interceptor)或过滤器(Filter)控制session。     spring为解决hibernate这一特性提供的解决方案,可以有效的控制session生命周期。

因为还没有讲到Spring,课堂上用过滤器(Filter)来控制session。

首先建个类OpenSessionInViewFilter继承Filter,重写doFilter方法,在try,finally中编写session的获得和关闭。实例代码如下:

public void doFilter(
        ServletRequest arg0,
        ServletResponse arg1,
        FilterChain chain)
                       throws IOException,   ServletException {
        try {
            HibUtil.getSession();
            chain.doFilter(arg0, arg1);
        } finally {
            HibUtil.closeSession();
        }
}

然后在web.xml配置文件中增加相关配置,例如:

<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>
        tarena.util.OpenSessionInViewFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>*.action</url-pattern>
 </filter-mapping>

最后要记得修改service层事务处理的代码,把关闭session的代码注释掉。

时间: 2024-10-31 10:54:26

hibernate的延迟加载及其与session关闭的矛盾的相关文章

延迟加载和session关闭的矛盾

延迟加载(no session or session was closed)就是并不是在读取的时候就把数据加载进来,而是等到使用时再加载. 那么Hibernate是怎么知道用户在什么时候使用数据了呢?又是如何加载数据呢? 其实很简单,它使用了代理机制.返回给用户的并不是实体本身,而是实体对象的代理.代理对象在用户调用getter方法时就会去数据库加载数据. 但加载数据就需要数据库连接.而当我们把会话关闭时,数据库连接就同时关闭了.这种情况就叫做未初始化的关系. 延迟加载与session关闭的矛盾

Hibernate的延迟加载问题

一.延迟加载及作用?    延迟加载又叫懒加载.是指在访问数据时,当数据用到的时候才被加载,没有被用到的时候不加载.二.这样做有什么好处呢?    好处就是每次访问数据的时候,因为只加载需要的数据,这样就可以降低数据库以及内存压力.    虽然说有时候整体的数据量并不多,但是这是一种机制,当数据量比较大的时候,对整体项目或者    方法调用的优化就会有明显的效果. 三.hibernate中get方法和load方法区别?    1.hibernate中,对于get方法,是立即加载的,也就是会立刻从

hibernate的延迟加载和抓取策略

一,延迟加载 1.实体类延迟加载 通过代理机制完成,由javassist类库实现运行时代理,修改实体类的字节码实现了运行时代理     <class lazy="true|false">     实体级别的延迟加载默认值为true,意味实体对象是延迟加载,只影响load方法.      <class lazy="true|false">其他查询方式都是立即加载              2.关联属性延迟加载 默认情况下除了<one-to

Hibernate中延迟加载和缓存

什么是延迟加载? 延迟加载是指当应用程序想要从数据库获取对象时(在没有设置lazy属性值为false),Hibernate只是从数据库获取符合条件的对象的OId从而生成代理对象,并没有加载出对象 访问该对象的属性时才会加载出相应的值.简答来说就是尽可能的减少查询的数据量. 如何配置延迟加载 在Hibernate中通过.hbm配置文件中的lazy属性来陪值,并且lazy属性出现的位置不同其作用和取值也不同.下面来详细介绍其在不同位置的不同取值和作用 类Class标签中的lazy: 在类标签Clas

5、Hibernate的延迟加载

1.session.load(User.class,1); 一:了解懒加载 Session session = null; try { session = HibernateUtil.openSession(); User u = (User)session.load(User.class, 1); //此时一条sql都没有发,这就是hibernate的延迟加载 /** * 延迟加载指的就是,当完成load操作之后,并不会马山发出sql语句,只有在使用到该对象时才会发出sql * 当完成load

1、Struts2和Hibernate的简单整合(带Session的管理方式)

1.关于数据库:是部门和员工的关系 关于entity和xx.hbm.xml的实现 Dept.class package cn.itcast.entity; import java.util.HashSet; import java.util.Set; public class Dept { private int deptId; private String deptName; // [一对多] 部门对应的多个员工 private Set<Employee> emps = new HashSe

Hibernate 的延迟加载

Hibernate 的延迟加载(lazy load)是一个被广泛使用的技术.这种延迟加载保证了应用只有在需要时才去数据库中抓取相应的记录.通过延迟加载技术可以避免过多.过早地加载数据表里的数据,从而降低应用的内存开销.Hibernate 的延迟加载本质上就是代理模式的应用,当程序通过 Hibernate 装载一个实体时,默认情况下,Hibernate 并不会立即抓取它的集合属性.关联实体所以对应的记录,而是通过生成一个代理来表示这些集合属性.关联实体,这就是代理模式应用带来的优势. 但是,延迟加

Hibernate SessionFactory的创建和session的获取

1,当我们调用 Configuration config=new Configuration().configure(); 时候Hibernate会自动在当前的CLASSPATH中搜寻hibernate.cfg.xml文件并将其读取到内存作为后继操作的基础配置. 我们也可以指定配置文件名,如果不希望使用默认的hibernate.cfg.xml文件作为配置文件的话: SessionFactory SessionFactory 负责创建Session的实例.我们可以通过Configuation实例创

Hibernate的懒加载session丢失解决方法

在web.xml加入spring提供的过滤器,延长session的生命周期 <!--Hibernate的懒加载session丢失解决方法 --> <filter> <filter-name>openSessionInView</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class&