aaberg / sql2o

sql2o is a small library, which makes it easy to convert the result of your sql-statements into objects. No resultset hacking required. Kind of like an orm, but without the sql-generation capabilities. Supports named parameters.
http://sql2o.org
MIT License
1.15k stars 229 forks source link

org.sql2o.Sql2oException: Error in executeUpdate, ORA-01000: maximum open cursors exceeded #312

Open zakjar opened 5 years ago

zakjar commented 5 years ago

I use ConnectionPool - org.apache.tomcat.jdbc.pool.DataSource My database is Oracle with 300 limit open cursor And this code finish with ORA-01000 Exception

for ( int i = 0; i < 400; i++ ) try(Connection con = AbsObject.getOpenedConnection() ) { con.createQuery("insert into xxx ( id ) values ( 1 )" ).executeUpdate();
con.commit();
}

this code is correct : when I use con.commit(false)

for ( int i = 0; i < 400; i++ ) try(Connection con = AbsObject.getOpenedConnection() ) { con.createQuery("insert into xxx ( id ) values ( 1 )" ).executeUpdate();
con.commit(false);
}

I see in source code problem in Connection.close() Code getSql2o().getQuirks().closeStatement(statement) is never call if I use commit(true), because connectionIsClosed is true

    if (!connectionIsClosed) {
        for (Statement statement : statements) {
            try {
                getSql2o().getQuirks().closeStatement(statement);
            } catch (Throwable e) {
                logger.warn("Could not close statement.", e);
            }
        }
        statements.clear();

I think that Connection.commit( boolean) for connection pool have to close preparedStatement. And Connection.commit needs to be changed like this :

public Connection commit(boolean closeConnection){
    try {
        jdbcConnection.commit();
    }
    catch (SQLException e) {
        throw new Sql2oException(e);
    }
    finally {
        if(closeConnection) {
            //  ------------  close all prepared statement -----------  new code -----------
            for (Statement statement : statements) {
                try {
                    getSql2o().getQuirks().closeStatement(statement);
                } catch (Throwable e) {
                    logger.warn("Could not close statement.", e);
                }
            }
            statements.clear();
            //  --------------------------------------------------------------   end new code -------
            this.closeJdbcConnection();
      }
    }
    return this;
}