code: public void closeAll(CmsDbContext dbc, Connection con, Statement stmnt, ResultSet res) {
  
          // NOTE: we have to close Connections/Statements that way, because a dbcp PoolablePreparedStatement
          // is not a DelegatedStatement; for that reason its not removed from the trace of the connection when it is closed.
          // So, the connection tries to close it again when the connection is closed itself;
          // as a result there is an error that forces the connection to be destroyed and not pooled
  
          if (dbc == null) {
              LOG.error(Messages.get().getBundle().key(Messages.LOG_NULL_DB_CONTEXT_0));
          }
  
          try {
              // first, close the result set
              if (res != null) {
                  res.close();
              }
          } catch (SQLException e) {
              LOG.debug(e.getLocalizedMessage(), e);
          } finally {
              res = null;
          }
  
          try {
              // close the statement
              if (stmnt != null) {
                  stmnt.close();
              }
          } catch (SQLException e) {
              LOG.debug(e.getLocalizedMessage(), e);
          } finally {
              stmnt = null;
          }
  
          try {
              // close the connection
              if ((con != null) && !con.isClosed()) {
                  con.close();
              }
          } catch (SQLException e) {
              LOG.debug(e.getLocalizedMessage(), e);
          } finally {
              con = null;
          }
  
      }
docs: Attempts to close the connection, statement and result set after a statement has been executed.<p>
  
  @param dbc the current database context
  @param con the JDBC connection
  @param stmnt the statement
  @param res the result set