记录一个最近在开发过程中遇到的问题。项目是用ssh做的。
场景:要查出一个列表,实体类如下
public class Item implements Serializable{ private static final long serialVersionUID = 7303799225184433737L; private Integer id; private Integer bidsId; private String name; private Double fullScore; private String standard; private String type; private List<Grade> companyGradeList; //setter and getter... }
需要查出所有人的itemList,对于每个人来说companyGradeList是不同的。
在action中循环查出每个人的itemList,部分代码如下
List<BidsEmp> emplist = (List<BidsEmp>)gradeService.findByExample(bemp); for(BidsEmp bmp:emplist) { List<Item> itl = (List<Item>) gradeService.getItemList(item, bmp.getEmpId(), companyList); for(Item it:itl) { List<Grade> glist = it.getCompanyGradeList(); for(Grade g:glist) { //System.out.println(g.getScore()); } } }
service层中的getItemList没什么特别,只是为每个item的companyGradeList赋值而已,因为companyGradeList没有在hbm文件中配置,只是额外加的一个属性。然后问题就出现了,所有人的companyGradeList都是一样的,都是最后的那个人的。
猜想是因为session一级缓存的问题,导致每次查出的itemList都是同一个。第一次会从数据库查,以后再查Item的时候因为session中已经有了,就直接拿的缓存中的。我在action中用下面的方法比较
Item item1 = null; Item item2 = null; List<BidsEmp> emplist = (List<BidsEmp>)gradeService.findByExample(bemp); List<Item> itl = (List<Item>) gradeService.getItemList(item, emplist.get(0).getEmpId(), companyList); item1 = itl.get(0); itl = (List<Item>) gradeService.getItemList(item, emplist.get(1).getEmpId(), companyList); item2 = itl.get(0); System.out.println(item1==item2);
print结果为true,也就是说两次拿到的Item是同一个对象。
但是我循环查询是在action中做的,没有在service中,session已经关闭了啊……忽然想起来项目中用到了OpenSessionInView,这样的话,session会在会话中一直保持打开。
<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
我将此配置去掉,再执行之前方法,print结果为false了。
解决办法:在service中每次做查询的时候new出Item对象,然后将查询到的Item进行BeanUtils.copyProperties,这样每次得到的结果都是不一样的。
相关推荐
### Spring + Hibernate OpenSessionInView 模式的理解和应用 在Java Web开发中,Spring与Hibernate作为两个重要的框架,经常被一起使用...但在使用时也需要注意其潜在的性能影响和其他风险,合理选择是否启用该模式。
在Java Web开发中,OpenSessionInView(OSIV)模式是一种常见的解决数据持久化问题的设计模式,主要用于Spring框架与Hibernate等ORM工具的集成。这个模式的主要目的是解决在HTTP请求处理过程中,由于Session范围内的...
为了练手培训,给大家准备的 Open Session In View 的简单例子,纯代码,大家可以参考...4.在页面上通过 jstl 很优雅的获取数据 5.通过 spring aop(aspectJ) 声明事务 6.通过formular 映射参数表,指定两个死的变量
然而,在没有使用Spring提供的`Open Session In View`的情况下,当懒加载设置为`true`时,如果在服务层(service or DAO)关闭了session,则需要在应用层内手动初始化所有关系集合(例如通过调用`company.getEmployees...
同时,需要注意的是,OpenSessionInView模式虽然方便,但也会带来潜在的问题,如事务边界不清晰和会话泄漏。因此,在实际应用中,应结合具体需求谨慎使用,并考虑使用更现代的解决方案,如Spring Data JPA的...
在实际应用中,需要注意的是,`OpenSessionInViewFilter`虽然解决了懒加载的问题,但同时也可能导致会话过长,增加内存占用和并发控制的复杂性。因此,合理地配置和使用这个过滤器是非常重要的。 最后,文件名列表...
OpenSessionInView(OSIV)模式是SSH整合中常见的一种优化策略,它在用户的一次HTTP请求过程中保持Hibernate Session,避免了多次打开和关闭Session,减少了N+1查询问题,提高了性能。 **Spring** 是一个全面的企业...
4. **错误隐蔽**:由于延迟加载在视图渲染阶段才执行,一些本应在业务逻辑中发现的错误可能会被延迟暴露。 `数据库.txt` 和 `osiv` 这两个文件名可能是与数据库操作和OSIV模式相关的资料。`数据库.txt` 可能包含了...
在Web开发中,OpenSessionInView模式能有效解决这个问题,但也要注意避免长时间占用Session资源。 其次,【抓取粒度】的调整也是关键。粒度决定了导航关联关系时预加载的数据量。通过设置batch-size,可以控制一次...
4. **懒加载问题**:OpenSessionInViewFilter能够解决懒加载对象在视图层抛出的异常,但不建议在视图层进行过多的数据库操作,因为这可能会导致N+1查询问题。 5. **替代方案**:随着技术的发展,如Spring Data JPA...
这样可以避免因事务过早关闭导致的懒加载问题,但需要注意不要在视图层进行大数据量的分页查询,以免内存溢出。 五、Page对象封装分页结果 为了更好地管理和展示分页数据,可以自定义一个Page对象,封装当前页数据...
在探讨Hibernate框架中的`lazy`属性时,我们深入解析了其功能、应用场景以及与之相关的潜在问题,尤其关注于如何有效利用此特性以优化数据库性能和应用响应速度。 ### Hibernate框架简介 Hibernate是一个开放源码...
4. **使用OpenSessionInView模式**:这是一种常用的做法,在Web请求开始时打开Session,在请求结束时关闭Session。这样可以在整个请求过程中安全地访问延迟加载的对象。 5. **自定义Session管理**:通过Spring管理...
懒加载是指Hibernate在访问对象时,可以延迟加载关联对象,直到真正访问到关联对象时才执行数据库查询。缓存分为一级缓存和二级缓存,一级缓存Session级共享,而二级缓存是SessionFactory级共享。配置Hibernate缓存...
- **OpenSessionInView**: 通过Web层的Filter在一次请求周期内保持Session打开,确保所有延迟加载的属性能在Session关闭前完成加载。 #### 八、Spring事务管理 **问题:** Spring支持几种事务管理方式?事务的隔离...
和Spring中OpenSessionInView由于org.springframework.web.struts.ContextLoaderPlugIn中保存同一个对象的名不同导致openSessionInView失效 稍微修改后在struts-config.xml中使用MyContextLoaderPlugIn.jar包中...
7. **延迟加载与OpenSessionInView**:延迟加载(Lazy Loading)意味着关联对象在需要时才加载,而OpenSessionInView过滤器确保在HTTP请求生命周期内保持Session打开,以支持延迟加载。 8. **Spring事务管理**:...
- 延迟加载是在需要时才加载关联对象,确保只在session范围内加载,以提高性能。 - `openSessionInView`模式是在Web层使用Filter打开和关闭Session,确保每个HTTP请求都有一个活跃的Session,以支持延迟加载。 6....
标题和描述指向的是一个关于Struts、Spring和Hibernate技术栈的面试题集合,这份文档旨在帮助准备面试的软件工程师理解并复习这些关键技术点。以下是基于给定内容的关键知识点的详细阐述: ### 1. Action的线程安全...