You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ibatis.apache.org by "Kevin Yang (JIRA)" <ib...@incubator.apache.org> on 2009/01/12 22:24:01 UTC

[jira] Issue Comment Edited: (IBATIS-535) iBatis not closing JDBC statements

    [ https://issues.apache.org/jira/browse/IBATIS-535?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12663098#action_12663098 ] 

kevinyang edited comment on IBATIS-535 at 1/12/09 1:22 PM:
------------------------------------------------------------

It's not a bug.  There is a un-documented SqlMap paramter "statementCachingEnabled", 

1. When statementCachingEnabled=true, the sessionScope will always cache the statement:

SessionScope.java

  public void putPreparedStatement(SqlMapExecutorDelegate delegate, String sql, PreparedStatement ps) {
    if (delegate.isStatementCacheEnabled()) {
      if (!isInBatch()) {
        if (hasPreparedStatementFor(sql))
          throw new SqlMapException("Duplicate prepared statement found.  This is likely a bug.");
        preparedStatements.put(sql, ps);
      }
    }
  }

So ps.close() will be by passed, that's because sessionScop cached the ps, sessionScope.hasPreparedStatement(ps)=true

  private static void closeStatement(SessionScope sessionScope, PreparedStatement ps) {
    if (ps != null) {
      if (!sessionScope.hasPreparedStatement(ps)) {
        try {
          ps.close();
        } catch (SQLException e) {
          // ignore
        }
      }
    }
  }

But all PS will be closed in SessionScope.closePreparedStatements()

  public void closePreparedStatements() {
    Iterator keys = preparedStatements.keySet().iterator();
    while (keys.hasNext()) {
      PreparedStatement ps = (PreparedStatement) preparedStatements.get(keys.next());
      try {
        ps.close();
      } catch (Exception e) {
        // ignore -- we don't care if this fails at this point.
      }
    }
    preparedStatements.clear();
  }

2. When statementCachingEnabled=false, the sessionScope will not cache the statement, and sessionScope.hasPreparedStatement(ps) is false, so the ps.close() will not be bypassed in  SqlExecutor.closeStatement()

      was (Author: kevinyang):
    It's not a bug.  There is a un-documented SqlMap paramter "statementCachingEnabled", 

1. When statementCachingEnabled=true, the sessionScope will always cache the statement:

SessionScope.java

  public void putPreparedStatement(SqlMapExecutorDelegate delegate, String sql, PreparedStatement ps) {
    if (delegate.isStatementCacheEnabled()) {
      if (!isInBatch()) {
        if (hasPreparedStatementFor(sql))
          throw new SqlMapException("Duplicate prepared statement found.  This is likely a bug.");
        preparedStatements.put(sql, ps);
      }
    }
  }

so the statement won't be closed in SqlExecutor.java, that's because sessionScop cached the ps
  private static void closeStatement(SessionScope sessionScope, PreparedStatement ps) {
    if (ps != null) {
      if (!sessionScope.hasPreparedStatement(ps)) {
        try {
          ps.close();
        } catch (SQLException e) {
          // ignore
        }
      }
    }
  }

But all PS will be closed in SessionScope.closePreparedStatements()

  public void closePreparedStatements() {
    Iterator keys = preparedStatements.keySet().iterator();
    while (keys.hasNext()) {
      PreparedStatement ps = (PreparedStatement) preparedStatements.get(keys.next());
      try {
        ps.close();
      } catch (Exception e) {
        // ignore -- we don't care if this fails at this point.
      }
    }
    preparedStatements.clear();
  }

2. When statementCachingEnabled=false, the sessionScope will not cache the statement, and sessionScope.hasPreparedStatement(ps) is false, so the PS will be closed immediately by SqlExecutor.closeStatement()
  
> iBatis not closing JDBC statements
> ----------------------------------
>
>                 Key: IBATIS-535
>                 URL: https://issues.apache.org/jira/browse/IBATIS-535
>             Project: iBatis for Java
>          Issue Type: Bug
>          Components: SQL Maps
>    Affects Versions: 2.3.2, 2.3.3
>         Environment: Windows XP, Windows 2003, JBoss 4.0.5GA, Java 6.x, Spring 2.5.5
>            Reporter: Doug Rothauser
>         Attachments: applicationContext-jta.xml, applicationContext-sr-dao.xml, SQLExcecutor Debug Screen Shot.jpg
>
>
> JDBC statements aren't being closed until the Connection is closed.  
> 18:11:57,182 WARN  [WrappedConnection] Closing a statement you left open, please do your own housekeeping
> java.lang.Throwable: STACKTRACE
> 	at org.jboss.resource.adapter.jdbc.WrappedConnection.registerStatement(WrappedConnection.java:576)
> 	at org.jboss.resource.adapter.jdbc.WrappedStatement.<init>(WrappedStatement.java:62)
> 	at org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.<init>(WrappedPreparedStatement.java:56)
> 	at org.jboss.resource.adapter.jdbc.WrappedConnection.prepareStatement(WrappedConnection.java:187)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy$TransactionAwareInvocationHandler.invoke(TransactionAwareDataSourceProxy.java:225)
> 	at $Proxy66.prepareStatement(Unknown Source)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 	at java.lang.reflect.Method.invoke(Method.java:597)
> 	at com.ibatis.common.jdbc.logging.ConnectionLogProxy.invoke(ConnectionLogProxy.java:53)
> 	at $Proxy67.prepareStatement(Unknown Source)
> 	at com.ibatis.sqlmap.engine.execution.SqlExecutor.prepareStatement(SqlExecutor.java:497)
> 	at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:175)
> 	at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteQuery(MappedStatement.java:221)
> 	at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(MappedStatement.java:189)
> 	at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryForObject(MappedStatement.java:120)
> 	at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:518)
> 	at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:493)
> 	at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:106)
> 	at org.springframework.orm.ibatis.SqlMapClientTemplate$1.doInSqlMapClient(SqlMapClientTemplate.java:273)
> 	at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:209)
> 	at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForObject(SqlMapClientTemplate.java:271)
> 	at com.fcci.surveyrequest.dao.SurveyRequestSourceDAOImpl.getPhid(SurveyRequestSourceDAOImpl.java:80)
> 	at com.fcci.surveyrequest.dao.SurveyRequestSourceDAOImpl.getSurveyRequest(SurveyRequestSourceDAOImpl.java:151)
> 	at com.fcci.ra.RaServlet.acountDetails(RaServlet.java:1268)
> 	at com.fcci.ra.RaServlet.doAction(RaServlet.java:322)
> 	at com.fcci.expresswrite.EwServlet.handleRequest(EwServlet.java:640)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.