要在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加这个注释延时加载就失效
分享到:
相关推荐
《Hibernate延迟加载详解》 Hibernate作为Java领域中的一个强大的对象关系映射框架,提供了许多优化数据库操作的策略,其中之一便是延迟加载(Lazy Loading)。延迟加载机制旨在减少不必要的性能消耗,只在真正需要...
本篇文章将通过图文并茂的方式详细介绍如何在MyEclipse环境下,利用Struts 1.2、Spring 2.0 和 Hibernate 3.1 来构建一个查询Oracle数据库中雇员信息的应用,并探讨Hibernate中延迟加载机制的使用方法。 #### 2. 软...
Spring MVC 和 Hibernate 是两个在 Java Web 开发中广泛使用的框架。Spring MVC 是 Spring 框架的一部分,主要用于构建前端控制器,处理 HTTP 请求并分发到相应的业务逻辑。而 Hibernate 则是一个强大的 ORM(对象...
7. **懒加载和立即加载**:Hibernate提供了懒加载和立即加载策略,懒加载延迟加载关联的对象,直到真正需要时才查询数据库;立即加载则是在获取父对象时一起加载关联的对象。`@LazyCollection(LazyCollectionOption....
在IT行业中,Spring、Hibernate和Struts是三个非常重要的开源框架,它们构成了经典的Java Web开发“铁三角”。这些框架在企业级应用开发中扮演着核心角色,因此掌握它们的运用和理解是求职者必备的技能之一。以下是...
### Struts+Spring+Hibernate面试知识点详解 #### 一、Struts2框架 **Struts2** 是基于 **Struts1** 的一个升级版本,它采用了更为简洁的MVC架构模型,增强了对Web开发的支持。Struts2的核心是 **Interceptor**...
以上是对Spring_Structs_Hibernate中的关键知识点的详细介绍,涵盖了Hibernate的工作原理、延迟加载机制、缓存机制、查询方式以及优化技巧,同时还详细解释了Struts的工作机制及其validate框架的工作原理。
一个简单的例子是在用户注册功能中使用Spring和Hibernate。首先,定义User实体类和对应的数据库表。然后,在DAO中实现添加用户的方法,通过SessionFactory获取Session,执行SQL语句。最后,使用`@Transactional`注解...
Hibernate3.2 版本引入了许多新特性,如延迟加载、批处理等,以提高性能和效率。 - **对象关系映射**:Hibernate 通过配置文件或注解将 Java 对象映射到数据库表中,简化了数据访问层的开发工作。 - **查询语言**:...
- 在 Spring 中使用 `scope="prototype"` 来管理 Action 的生命周期,确保每个请求都对应一个新实例。 #### 2. MVC 架构下 Struts 如何实现 M-V-C? - **模型 (Model)**:由 JavaBean 或者 POJO 组成,用于封装...
声明式事务管理则通常在Spring框架中使用,通过@Transactional注解实现。 **四、查询语言HQL** Hibernate提供了一种面向对象的查询语言——HQL(Hibernate Query Language),类似于SQL,但操作的是对象而不是表格...
- **OpenSessionInViewFilter**:此过滤器确保在视图渲染过程中保持一个打开的Hibernate Session,这对于事务管理和延迟加载特别有用。 #### 2. struts-config.xml的配置调整 在Struts配置文件中,为了与Spring...
《Hibernate、Spring和Struts工作原理及使用理由详解》 在Java Web开发中,Hibernate、Spring和Struts是三大核心框架,它们各自扮演着不同的角色,共同构建了强大的企业级应用解决方案。 首先,让我们深入了解...
8. **处理Hibernate延迟加载**:使用`OpenSessionInViewFilter`过滤器,确保Session在整个HTTP请求期间保持打开状态,解决懒加载问题。配置过滤器映射到所有.do请求。 9. **处理只读模式异常**:由于...
7. **性能优化**:讨论如何通过优化配置、批处理、延迟加载、懒加载等手段提高Hibernate的运行效率,减少数据库访问。 8. **实体生命周期**:详解Hibernate对对象状态的管理,包括瞬时态、持久态、游离态和脱管态,...
Hibernate的二级缓存和延迟加载机制也有助于优化性能。 此外,这三大框架的集成是通过Spring的ApplicationContext进行的,它可以管理和协调Struts和Hibernate的配置,实现各组件之间的无缝连接。Spring的AOP还可以...