`
xtuhcy
  • 浏览: 142541 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在spring中使用hibernate延迟加载详解

阅读更多

要在spring中使用hibernate的延迟加载,我们先要模拟一个延迟加载的场景。

hibernate的get和load的区别相信大家都知道,load是通过代理加载实体,如果只访问id是不会读库将所有属性加载进来的,这个就是一个延迟加载的简单场景。

 

一、如果按照标准的spring+hibernate的整合,当使用load加载一个实体是,会报no session的错误

这是因为,延迟加载需要在同一个session中,如果按照标签配置,session在load后就已经关闭,因此页面上显示实体属性时通过代理延迟加载便会报no session的错误了。

解决办法,spring中提供了一个OpenSessionInViewFilter的filter用来在一个http请求中保持hibernate的session,配置如下:

<filter>
     <filter-name>hibernateLazyFilter</filter-name>
     <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
 <filter-mapping>
     <filter-name>hibernateLazyFilter</filter-name>
     <url-pattern>/*</url-pattern>
 </filter-mapping>

到此,就能解决延迟加载的问题吗?请往下看

 

二、此时查询数据库均没问题,但是当update一个实体,会报Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into 错误

这是因为,使用了OpenSessionInViewFilter后,spring会把hibernate的FlushMode改为FlushMode.NEVER,FlushMode.NEVER是不允许更新修改数据库操作的。

解决办法:

1.使用事务控制修改FlushMode

<property name="transactionAttributes">
            <props>
                <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
                <prop key="save*">PROPAGATION_REQUIRED</prop>
                <prop key="add*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="remove*">PROPAGATION_REQUIRED</prop>
            </props> 
</property>

这里不具体解释了,声明式事务的概念说起来也很多,需要注意的是HibernatTemplate的flushMode要设置为commit。

2.修改OpenSessionInViewFilter的属性,改为AUTO

<filter>
     <filter-name>hibernateLazyFilter</filter-name>
  <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
   <init-param> 
   <param-name>flushMode</param-name>
   <param-value>AUTO</param-value>
  </init-param>  
 </filter>

这里我们使用的是第二种方式。

三、到此查询修改操作不会再报错了,是不是已经配置好了呢?仔细一看,修改是没报错了,但是修改的结果并没有写入数据库

这是因为,spring在flush时会判断一下,请详见spring的源代码:

HibernateTemplate.doExecute{

......

flushIfNecessary(session, existingTransaction);

......

}

 

protected void flushIfNecessary(Session session, boolean existingTransaction) throws HibernateException {
  if (getFlushMode() == FLUSH_EAGER || (!existingTransaction && getFlushMode() != FLUSH_NEVER)) {
   logger.debug("Eagerly flushing Hibernate session");
   session.flush();
  }
 }

意思就是,spring的flushmode为FLUSH_EAGER || (flushmode不是FLUSH_NEVER && 不是事务)

很遗憾使,用了OpenSessionInViewFilter后,existingTransaction=true,也就是说此时spring认为是一个事务

 

解决办法:

1.将HibernateTemplate的flushmode设置为FLUSH_EAGER

2.既然spring不能自动flush,咱们就自己来吧,在update()后flush()

 

到此,延迟加载已经可以正常使用了。

 

 

 

附:在调试是还遇到过这样一个错误:

a different object with the same identifier value was already associated with the session。

这是因为在session的生命周期中如果存在多个实体,hibernate不知道以哪个为准,可以用evict、clear、merg解决

 

@NotFound(action=NotFoundAction.IGNORE)

many-to-one加这个注释延时加载就失效

0
0
分享到:
评论

相关推荐

    Hibernate延迟加载介绍.doc

    《Hibernate延迟加载详解》 Hibernate作为Java领域中的一个强大的对象关系映射框架,提供了许多优化数据库操作的策略,其中之一便是延迟加载(Lazy Loading)。延迟加载机制旨在减少不必要的性能消耗,只在真正需要...

    struts1.2+spring2.0+hibernate3.1集成开发详解

    本篇文章将通过图文并茂的方式详细介绍如何在MyEclipse环境下,利用Struts 1.2、Spring 2.0 和 Hibernate 3.1 来构建一个查询Oracle数据库中雇员信息的应用,并探讨Hibernate中延迟加载机制的使用方法。 #### 2. 软...

    Spring MVC + hibernate 集合

    Spring MVC 和 Hibernate 是两个在 Java Web 开发中广泛使用的框架。Spring MVC 是 Spring 框架的一部分,主要用于构建前端控制器,处理 HTTP 请求并分发到相应的业务逻辑。而 Hibernate 则是一个强大的 ORM(对象...

    hibernate对应关系详解

    7. **懒加载和立即加载**:Hibernate提供了懒加载和立即加载策略,懒加载延迟加载关联的对象,直到真正需要时才查询数据库;立即加载则是在获取父对象时一起加载关联的对象。`@LazyCollection(LazyCollectionOption....

    spring+hibernate+struts企业面试题(精华)

    在IT行业中,Spring、Hibernate和Struts是三个非常重要的开源框架,它们构成了经典的Java Web开发“铁三角”。这些框架在企业级应用开发中扮演着核心角色,因此掌握它们的运用和理解是求职者必备的技能之一。以下是...

    Spring_Structs_Hibernate

    以上是对Spring_Structs_Hibernate中的关键知识点的详细介绍,涵盖了Hibernate的工作原理、延迟加载机制、缓存机制、查询方式以及优化技巧,同时还详细解释了Struts的工作机制及其validate框架的工作原理。

    hibernate和spring笔记

    一个简单的例子是在用户注册功能中使用Spring和Hibernate。首先,定义User实体类和对应的数据库表。然后,在DAO中实现添加用户的方法,通过SessionFactory获取Session,执行SQL语句。最后,使用`@Transactional`注解...

    spring2.5+hibernate3.2+struts2.0组合配置说明

    Hibernate3.2 版本引入了许多新特性,如延迟加载、批处理等,以提高性能和效率。 - **对象关系映射**:Hibernate 通过配置文件或注解将 Java 对象映射到数据库表中,简化了数据访问层的开发工作。 - **查询语言**:...

    struts spring hibernate面试题

    - 在 Spring 中使用 `scope="prototype"` 来管理 Action 的生命周期,确保每个请求都对应一个新实例。 #### 2. MVC 架构下 Struts 如何实现 M-V-C? - **模型 (Model)**:由 JavaBean 或者 POJO 组成,用于封装...

    经典hibernate配置详解

    声明式事务管理则通常在Spring框架中使用,通过@Transactional注解实现。 **四、查询语言HQL** Hibernate提供了一种面向对象的查询语言——HQL(Hibernate Query Language),类似于SQL,但操作的是对象而不是表格...

    struts_hibernate_spring集成

    - **OpenSessionInViewFilter**:此过滤器确保在视图渲染过程中保持一个打开的Hibernate Session,这对于事务管理和延迟加载特别有用。 #### 2. struts-config.xml的配置调整 在Struts配置文件中,为了与Spring...

    Hibernate、Spring和Struts工作原理及使用理由

    《Hibernate、Spring和Struts工作原理及使用理由详解》 在Java Web开发中,Hibernate、Spring和Struts是三大核心框架,它们各自扮演着不同的角色,共同构建了强大的企业级应用解决方案。 首先,让我们深入了解...

    Struts+Hibernate+Spring的整合方法

    8. **处理Hibernate延迟加载**:使用`OpenSessionInViewFilter`过滤器,确保Session在整个HTTP请求期间保持打开状态,解决懒加载问题。配置过滤器映射到所有.do请求。 9. **处理只读模式异常**:由于...

    精通Hibernate:Java持久化对象技术详解[第二版]

    7. **性能优化**:讨论如何通过优化配置、批处理、延迟加载、懒加载等手段提高Hibernate的运行效率,减少数据库访问。 8. **实体生命周期**:详解Hibernate对对象状态的管理,包括瞬时态、持久态、游离态和脱管态,...

    网上订餐系统(struts+spring+hibernate)130221.zip

    Hibernate的二级缓存和延迟加载机制也有助于优化性能。 此外,这三大框架的集成是通过Spring的ApplicationContext进行的,它可以管理和协调Struts和Hibernate的配置,实现各组件之间的无缝连接。Spring的AOP还可以...

Global site tag (gtag.js) - Google Analytics