`
hz_chenwenbiao
  • 浏览: 1010146 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

SSH 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 implementsItemDAO {
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问题就没了。(若以后有相关问题再继续讨论)
=================无耻分割线,以下是本人的一点小总结=============================
由于我在SSH整合中使用的getSession()方式进行数据库访问
最开始的解决办法是使用Session se=getSession(); se.close()来关闭连接,可是不想却没有任何效果
于是又找到OpenSessionInViewFilter 的方式还是不能解决,
最后采用的是
Session session = super.getSession();
String hql = "from Item as i";
List l = session.createQuery(hql).list();
releaseSession(session);
问题圆满解决!呵呵

分享到:
评论

相关推荐

    Jmeter解决SSH连接数据库

    ### JMeter通过SSH连接远程数据库解决方案 #### 项目背景与需求分析 在当前项目中,存在三台机器:远程数据库服务器、跳板机以及客户端。其中远程数据库服务器的IP地址为192.168.125.130,跳板机的IP地址为192.168...

    SSH2连接Oracle数据库的例子

    5. **SSH连接设置**:除了数据库连接信息,还需要SSH的凭据,包括SSH服务器的主机名、端口、用户名和私钥文件(如果使用公钥认证)。 6. **代码实现**:在Java程序中,使用JSch库创建SSH隧道,然后通过隧道建立到...

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

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

    SSH连接MySQL的Jar包

    6. **关闭资源**:完成数据库操作后,确保关闭`Statement`、`Connection`以及SSH会话,以释放资源。 理解这些概念和技术对于任何Java开发者来说都是至关重要的,特别是那些处理敏感数据或在不安全的网络环境中工作...

    使用qt 6在windows下学习开发串口、网络通信、ssh远程连接等

    在本文中,我们将深入探讨如何使用Qt 6框架在Windows环境下进行串口、网络通信以及SSH远程连接的开发。Qt是一个强大的跨平台应用程序开发框架,它提供了丰富的库和工具,使得开发者可以方便地构建GUI应用和系统级...

    Android使用JDBC+SSH连接外网数据库

    7. **关闭资源**:在操作完成后,记得关闭JDBC连接、Statement以及SSH Session,以释放资源。 在实际应用中,考虑到性能和安全因素,建议使用异步任务或后台服务来处理数据库操作,避免阻塞UI线程。同时,敏感信息...

    android 集合SSH客户端实现登录,并保持session访问服务端数据

    - SSH连接一旦建立,可以通过`Session`对象维持会话。在Android应用中,我们通常需要将`Session`对象保存在一个单例类或者使用`SharedPreferences`存储其状态,以便在后续的操作中复用,减少连接创建的开销。 4. *...

    java远程telnet ftp和ssh连接的方法

    本文将详细介绍如何使用Java实现对远程服务器的Telnet、SSH(Secure Shell)和FTP(File Transfer Protocol)连接。 1. **Java连接Telnet** Telnet是一种协议,允许用户通过网络在远程主机上执行命令。在Java中,...

    java进行ssh协议连接的jar包jsch-0.1.54.jar

    在完成所有操作后,记得关闭SSH连接: ```java session.disconnect(); ``` JSch库还支持其他高级功能,如端口转发和代理设置。开发者可以根据需要调整配置和使用不同的通道类型来满足各种场景的需求。总之,...

    ssh.rar_qt ssh_qtssh_qt中调用ssh_qt使用ssh_ssh qt

    3. 执行远程命令:连接成功后,可以使用`SshSession`的`executeCommand`方法执行Linux命令。这个方法返回一个`SshProcess`对象,可以用来获取命令的输出和错误信息。 ```cpp SshProcess process = session.execute...

    java连接linux,执行shell命令的工具类 sshxcute.jar

    5. **关闭连接**:执行完所有操作后,记得关闭`SshSession`以释放资源。 示例代码如下: ```java import com.sshtools.j2ssh.SshClient; import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient;...

    SSH连接远程服务器的一个简单的工程

    5. **关闭连接**:完成所有操作后,别忘了关闭`Channel`和`Session`以释放资源。 此外,提到的"Log4j的简单配置"表明项目中还包含了日志管理部分。Log4j是Apache的一个开源日志框架,广泛应用于Java应用中,提供...

    SSH2 java连接远程服务器框架

    在Java中,实现SSH2连接远程服务器的功能通常需要借助第三方库,如JSch或Apache MINA。本教程将详细介绍如何使用Java通过SSH2框架连接到远程服务器。 一、JSch库的使用 JSch是一个纯Java实现的SSH2库,它允许开发者...

    (接上篇博客)Java SSH远程执行Shell脚本实现

    首先,为了实现SSH连接和命令执行,我们需要一个Java库,如JSch(Java Secure Channel)。JSch是一个纯Java实现的SSH2库,提供了对SFTP、SCP和SSH命令的支持。要使用JSch,你需要将其添加到项目的类路径中。 下面是...

    trilead-ssh2 for java

    Trilead SSH2库为Java开发者提供了一套强大的SSH(Secure Shell)实现,使得在Java应用中实现SSH连接变得简单而高效。本文将深入探讨Trilead SSH2库的功能、使用方法以及相关实践。 一、Trilead SSH2库简介 Trilead...

    ganymed-ssh2-build210

    1. **连接管理**:创建、维护和关闭到远程SSH服务器的连接。 2. **身份验证**:支持多种身份验证方式,如公钥/私钥对、密码认证以及键盘交互式认证。 3. **会话管理**:建立会话通道,通过该通道可以执行命令、打开...

    安卓SQLite数据库相关-Android使用JDBCSSH连接外网数据库.rar

    6. **处理结果**:获取并处理查询结果,关闭数据库连接和SSH隧道。 需要注意的是,由于Android的安全性和权限限制,直接在主线程中执行这些耗时的操作可能导致ANR(Application Not Responding)。因此,通常建议...

    ganymed-ssh2-262.jar

    6. **关闭连接**:在完成所有操作后,务必关闭`Session`和`Connection`以释放资源。 标签“ganymed java链接ssh”强调了这个库是Java开发中的SSH连接工具。在实际开发中,Ganymed SSH2库提供了丰富的API,可以处理...

    ganymed-ssh2 工具类

    此外,使用完毕后,务必调用`disconnect()`方法断开SSH连接,以及关闭`Session`和`Sftp`会话。 ```java try { // SSH操作... } catch (IOException e) { e.printStackTrace(); } finally { if (conn.isConnected...

    java SSH FTP下载文件

    4. **建立连接**:调用`session.connect()`方法建立SSH连接。 5. **打开SFTP通道**:SSH连接建立后,可以打开SFTP(Secure File Transfer Protocol)通道,它基于SSH提供文件传输服务。 ```java ChannelSftp sftp...

Global site tag (gtag.js) - Google Analytics