`
fantlam
  • 浏览: 99113 次
  • 性别: Icon_minigender_1
  • 来自: 佛山
社区版块
存档分类
最新评论

我的SSH项目之旅(6.session问题解决)

阅读更多
2008-07-20 22:25:27,531 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2008-07-20 22:25:27,609 INFO [org.springframework.jdbc.support.SQLErrorCodesFact

ory] - SQLErrorCodes loaded: [DB2, HSQL, MS-SQL, MySQL, Oracle, Informix, PostgreSQL, Sybase]


2008-07-20 22:26:48,437 WARN [org.hibernate.jdbc.ConnectionManager] - finalizingwith closed connection
2008-07-20 22:26:48,437 WARN [org.hibernate.jdbc.ConnectionManager] - unclosed connection, forgot to call close() on your session?




Hibernate: select item0_.itemid as itemid, item0_.itemname as itemname1_, item0_.itemcode as itemcode1_ from item item0_
2008-07-22 20:54:56,375 WARN [org.hibernate.jdbc.ConnectionManager] – finalizing with closed connection


2008-07-22 20:56:32,812 WARN [org.hibernate.util.JDBCExceptionReporter] - SQL Error: 0, SQLState: null
2008-07-22 20:56:32,812 ERROR [org.hibernate.util.JDBCExceptionReporter] - Cannot get a connection, pool error Timeout waiting for idle object
2008-07-22 20:56:32,828 WARN [org.hibernate.util.JDBCExceptionReporter] - SQL Error: 0, SQLState: null
2008-07-22 20:56:32,828 ERROR [org.hibernate.util.JDBCExceptionReporter] - Cannot get a connection, pool error Timeout waiting for idle object
org.hibernate.exception.GenericJDBCException: Cannot open connection

终于找到解决办法了 ,我们来看下面的内容吧
ItemDAOImpl.java
public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {

  public List queryAll() throws Exception {
    // TODO Auto-generated method stub
    Session session=super.getSession(true);
    String hql="from Item as i";
    List l=super.getSession().createQuery(hql).list();
    return l;
}
}\
其实上面的代码隐藏了一个问题,数据库连接并没有被关闭,所以一直出现以上的问题。
我这里提供三个解决方案
方案一:
用此种方法,虽然没有手动关闭数据库连接,但spring已经帮我们关闭了
return super.getHibernateTemplate().find(hql);
方案二:(经测试,此方案比较有效)
设定HibernateTemplateAllowCreateTrue
spring API HibernateDaoSupport
protected net.sf.hibernate.Session getSession(boolean allowCreate)
      Get a Hibernate Session, either from the current transaction or a new one.
public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {

  public List queryAll() throws Exception {
    // TODO Auto-generated method stub
    Session session=super.getSession(true);
    String hql="from Item as i";
      List l=session.createQuery(hql).list();
    try{
      return l;
    }finally{
    session.close();
    }
}
}
方案三:
Spring API:
geSession()
org.springframework.orm.hibernate3.support.HibernateDaoSupport 中的一个方法,

它可以从当前事务或者一个新的事务获得一个hibernate 
session.
通常使用releaseSession(org.hibernate.Session)方法与getSession()配合。

如果没有绑定线程,releaseSession关闭由这个DAOSessionFactory创建的Hibernate Session。 
修改后的代码如下:

public class ItemDAOImpl extends HibernateDaoSupport implements ItemDAO {
  public List queryAll() throws Exception {
    // TODO Auto-generated method stub
    Session session = super.getSession();
    String hql = "from Item as i";
    List l = session.createQuery(hql).list();
    releaseSession(session);

  }
}
困扰了几天的问题终于解决了,项目搁浅了好几天了,就是对springsession的管理不清楚。

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: dj.fantlam.myssh.vo.Item.subitems - no session or session was closed

这是一个关于延迟加载的问题
applicationContext.xml加入
<bean id="hibernateInterceptor"
  class="org.springframework.orm.hibernate3.HibernateInterceptor">
    <property name="sessionFactory">
      <ref bean="sessionFactory" />
    </property>
  </bean>
在业务逻辑层中使用延迟加载
  
即使在视图外面,Spring框架也通过使用AOP 拦截器 HibernateInterceptor来使得延迟加载变得很容易实现。这个Hibernate 拦截器透明地将调用配置在Spring应用程序上下文中的业务对象中方法的请求拦截下来,在调用方法之前打开一个Hibernate会话,然后在方法执行完之后将会话关闭。



以及 Item.hbm.xml  
<set name="subitems" inverse="true" cascade="all” talbe=”subitem” 表示一对多 lazy="false" order-by="subcode">
        <key>
          <column name="itemid" />
        </key>
        <one-to-many class="dj.fantlam.myssh.vo.Subitem" />
    </set>
问题得以解决

上网查了一些资料
hibernate一对多session关闭问题
  <filter>
    <filter-name>opensession</filter-name>
    <filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
  </filter>
  <filter-mapping>
    <filter-name>opensession</filter-name>
    <url-pattern>*.do</url-pattern>
  </filter-mapping>
openSessionInView的意思就是延长session的生命周期,到了jsp层,session依然有效,所以就可以正确读取一对多的多方的属性值了

2008-07-25 21:47:31,031 ERROR [org.apache.catalina.core.ContainerBase.[Catalina]
.[localhost].[/myssh].[jsp]] - Servlet.service() for servlet jsp threw exception

java.lang.IllegalStateException: getOutputStream() has already been called for this response

原因是image.jsp的问题   由于jsp container在处理完成请求后会调用releasePageContet方法释放所用的PageContext object,并且同时调用getWriter方法,由于getWriter方法与在jsp页面中使用流相关的getOutputStream方法冲突,所以会造成这种异常,

解决方法 在最后加上

out.clear();
out = pageContext.pushBody();


Question.hbm.xml
  <set name="answers" inverse="true" table="answer">
        <key>
          <column name="qid" />
        </key>
        <one-to-many class="dj.fantlam.myssh.vo.Answer" />
    </set>




刚刚在http://localhost:8888/myssh/jsp/show.do?qid=6&status=selectid这块出现了延迟加载的问题,也就是question_show.jsp
  <logic:iterate id="ans" name="question" property="answers">
  </logic:iterate> answers的时候没读到
然后我在Question.hbm.xml加上lazy="false"就行了
<set name="answers" inverse="true" table="answer" lazy="false">
        <key>
          <column name="qid" />
        </key>
        <one-to-many class="dj.fantlam.myssh.vo.Answer" />
</set>


今天我又发现了一个问题,原来之前的解决方案是多余的。我就是觉得很奇怪,前段日子就是怎么测都是session关闭了,真的很莫名其妙。实际上OpenSessionInViewFilter这个配置就是解决在websession的问题,而之前我配了之后不起作用,现在想想原因应该是tomcat里的项目之间的干扰吧,因为如今我把一些别的项目去掉了,问题就没了(不过当时我是有在虚拟机做测试的,一个新的tomcat也同样出问题,百思不得其解,再测试一下再说吧,以后有问题再补充)。害得我走了冤枉路,还到论坛里问了许久。总结一下,就是利用hibernateTemplate或者是直接利用hibernateDAOSupport类来取得session 这两种方法都可以自动处理session的,前一种是spring机制,而后一种是hibernate机制。
2008-08-06 17:15:13,272 INFO [org.springframework.orm.hibernate3.support.OpenSessionInViewFilter] - Initializing filter 'opensession'
2008-08-06 17:15:13,444 INFO [org.springframework.core.CollectionFactory] - JDK 1.4+ collections available
2008-08-06 17:15:13,475 INFO [org.springframework.core.CollectionFactory] - Commons Collections 3.x available
2008-08-06 17:15:13,490 INFO [org.springframework.orm.hibernate3.support.OpenSessionInViewFilter] - Filter 'opensession' configured successfully
经过测试 不配置OpenSessionInViewFilter的话在网页读取的时候就会发生session问题



网上有这么一种说法
---------------------------------------------------------------------------------------------------
strutsspring的整合是在struts-config.xml里加了个plugin

<plug-in
  className="org.springframework.web.struts.ContextLoaderPlugIn">
    <set-property property="contextConfigLocation"
      value="/WEB-INF/classes/applicationContext.xml" />
  </plug-in>
这一段必须去掉
web.xml加上
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
保证openSessionInView的正常使用
经过我的测试,此方法有道理。我们先来看看spring整合struts的方法吧。两者整合的一种通用配置:在web.xml中加入一下任意一种
1
  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>

2
  <servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>
    org.springframework.web.context.ContextLoaderServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

为了让spring ApplicationContext实例化,作为IOC容器,必须优先加载,一种常见的做法是在web.xml加载spring容器。所以以上2种方法都是一样的,ContextLoaderListenerContextLoaderServlet底层都依赖ContextLoader,因此两者效果几乎没有什么区别。在Servlet2.3标准中才出现ContextLoaderListener,它比ContextLoaderServlet会优先加载。

现在我得出的结论是之前是OpenSessionInViewFilter不起作用,如果我不把plugin
去掉的话问题依旧。经过测试,我不加plugin问题就没了。(若以后有相关问题再继续讨论)
分享到:
评论
1 楼 zhjkzjf 2010-01-05  
你好,我现在也出现了spring管理数据库连接没有关闭的问题,不过不是用Hibernate,而是用SimpleJdbcTemplate simpleJdbcTemplate直接执行SQL语句,所以你上面的方法可能有点不适合我,能给我个建议吗?谢谢。

相关推荐

    Java(通过ganymed-ssh2-build210.jar)实现SSH远程连接linux终端

    Java通过ganymed-ssh2-build210.jar库实现SSH远程连接Linux终端是一个常见的应用场景,主要用于自动化运维、系统管理或者开发过程中需要与Linux服务器交互的场景。ganymed-ssh2-build210.jar是Java的一个开源SSH库,...

    ganymed-ssh2-build210.jar java远程访问linux服务器操作、上传下载文件

    import ch.ethz.ssh2.Session; import ch.ethz.ssh2.StreamGobbler; import common.Logger; import org.apache.commons.lang.StringUtils; import java.io.*; import java.util.logging.Level; /** * SCP远程访问...

    Node.js-WebSSH2基于Web的SSH2客户端使用xterm.jssocket.io和ssh2实现

    在本项目中,"Node.js-WebSSH2基于Web的SSH2客户端使用xterm.js、socket.io和ssh2实现",我们关注的是构建一个在浏览器环境中运行的SSH2客户端。这个客户端允许用户通过Web界面安全地连接到远程服务器执行命令,从而...

    SSH框架Maven项目pom.xml

    SSH框架Maven项目pom.xml

    ssh8.7-el6.tar.gz

    在安装过程中,可能遇到的问题包括依赖冲突、权限问题、硬件兼容性等,解决这些问题通常需要查阅官方文档、社区论坛或者通过搜索引擎寻找解决方案。在生产环境中,确保备份现有设置并测试新版本的功能和性能是至关...

    SSH项目的实现步骤.doc

    SSH 项目实现步骤 SSH 项目的实现步骤可以分为五个步骤:导入页面、导入数据库驱动、添加 Struts 框架、建立 entity 包和完成登录操作。 第一步:导入页面 在实现 SSH 项目的第一步是导入页面,将页面资料复制到...

    ssh 例子 有问题 www.willvc.com.cn 能联系到我

    ssh 例子 ssh 例子 有问题 www.willvc.com.cn 能联系到我

    ganymed-ssh2-build250.rar,jar包,源码,例子,javadoc

    由于其全面的SSH2支持和良好的文档,Ganymed SSH2成为了Java开发者在处理SSH相关任务时的首选库之一。 总结起来,Ganymed SSH2 Build 250是一套全面的SSH2工具包,它提供了所有必要的组件,从运行时库到开发辅助...

    j2ssh-core-0.2.2.jar

    SSHTools是一组Java SSH应用程序。包括:Java SSH API, SSH Terminal, SSH secured VNC客户端, SFTP客户端和SSH Daemon。ESftp是根据此项目开发的一个Eclipse插件主要用来在Eclipse开发平台与Sftp服务器之间传输文件...

    ganymed-ssh2-262.jar

    标题中的“ganymed-ssh2-262.jar”是一个特定版本的SSH2库,由Ganymed项目提供,用于Java环境下的SSH(Secure Shell)连接。SSH是一种网络协议,常用于安全地远程登录到服务器、传输文件以及执行命令。Ganymed SSH2...

    SSH报cannot establish connection,怎么办.答解决方法.把xx改成yes即可解决

    针对这个问题,我们可以采取一些解决措施,正如标题和描述中提到的,修改一个特定的设置可能就能解决问题。 首先,我们需要了解SSH服务器的配置文件,这个文件通常是`/etc/ssh/sshd_config`。在这个文件中,有一个...

    ganymed-ssh2-build210.jar

    Ganymed SSH2是一个开源项目,为Java开发者提供了丰富的功能,包括连接到Linux服务器、执行命令、传输文件等。 描述中提到的“java操作linux命令”的功能,意味着这个jar包提供了API接口,允许Java程序通过SSH连接...

    ssh2_lib.rar

    ssh2_lib.rar与csdn中的ssh2_src.rar是整个项目,把ssh2_lib.rar下载后,直接放在ssh2_src.rar中的\ssh2_src\SSH2\web\WEB-INF目录下,再配置一下mysql就可以使用了. ssh2_src.rar下载地址: ... ssh2_src.rar的具体使用,...

    Node.js-ssh2-一个SSH2客户端和服务器node.js模块

    本文将深入探讨 `ssh2` 模块的核心概念、功能以及如何在实际项目中应用。 ### SSH2 协议简介 SSH(Secure Shell)是一种网络协议,用于在不安全的网络上提供安全的远程登录和其他网络服务。它通过加密技术确保数据...

    用IDEA创建一个SSH项目.doc

    IDEA 中创建 SSH 项目的详细步骤和配置 在本文中,我们将详细介绍如何使用 IDEA 创建一个 SSH 项目,包括项目的创建、配置和启动过程。 创建 Maven Web 项目 首先,我们需要在 IDEA 中创建一个新的 Maven 项目。...

    D:\笔记\ssh整合项目基本流程.txt

    对于初学java框架的小伙伴而言或许有所帮助,若你对框架开发实际项目经验不足,可下载参照此文档,帮你梳理ssh项目开发的基本配置与流程,有助于你快速进入熟悉开发过程与ssh环境搭建的相关步骤

    SSH启动失败解决方法.docx

    在解决 SSH 启动失败问题时,可能会出现以下错误: `/var/empty/sshd must be owned by root and not group or world-writable.` 这时,需要确保 `/var/empty/sshd` 目录的所有权属于root用户,并且其权限设置为不...

    ganymed-ssh2-build261.jar,还有源码

    通过查看源码,开发者可以学习如何使用Ganymed SSH2 API,理解各种功能的工作原理,并可能发现或解决潜在的问题。 Ganymed SSH2的源码结构清晰,注释详尽,遵循了良好的编程实践。主要类包括`Connection`,负责建立...

Global site tag (gtag.js) - Google Analytics