Product & build: SmartGWT 13.0 (server & client), build 2025-09-26
Database: Oracle 19c
JDBC driver: com.oracle.database.jdbcjdbc11:23.9.0.25.07
Server logs class: com.isomorphic.sql.SQLDriver, com.isomorphic.sql.SQLDataSource
Reproducibility: Always
Severity: High (batch inserts fail with ORA-01000)
Summary:
When inserting many rows via a SQL DataSource (server-side DSRequest with operationType=ADD), SmartGWT executes an extra reselect per insert:
Each reselect appears to open a new Oracle cursor that is not closed. After roughly ~300 inserts in one run, the session hits:
ORA-01000: maximum open cursors exceeded
I’m convinced that in the part of the code where the “Executing ROWID query:” debug message is generated in the SQLDriver class, a statement is opened and not closed—for example, it’s missing a statement.close() in a finally block.
The issue does not reproduce when I provide the PK value before the INSERT (i.e., I pre-generate ID and include it in the ADD request). In this mode, the server does not issue the post-INSERT ROWID reselect (no Executing ROWID queryline in logs), and the session’s open-cursor count stays flat — no ORA-01000.
log:
This is my DDL:
DataSource:
ORACLE logging:
OracleLog.properties file:
Database: Oracle 19c
JDBC driver: com.oracle.database.jdbcjdbc11:23.9.0.25.07
Server logs class: com.isomorphic.sql.SQLDriver, com.isomorphic.sql.SQLDataSource
Reproducibility: Always
Severity: High (batch inserts fail with ORA-01000)
Summary:
When inserting many rows via a SQL DataSource (server-side DSRequest with operationType=ADD), SmartGWT executes an extra reselect per insert:
Code:
SELECT OSOBA.ID, OSOBA.IMIE, OSOBA.NAZWISKO, OSOBA.WIEK FROM MSDATA.OSOBA WHERE ROWID = :rowid
ORA-01000: maximum open cursors exceeded
I’m convinced that in the part of the code where the “Executing ROWID query:” debug message is generated in the SQLDriver class, a statement is opened and not closed—for example, it’s missing a statement.close() in a finally block.
The issue does not reproduce when I provide the PK value before the INSERT (i.e., I pre-generate ID and include it in the ADD request). In this mode, the server does not issue the post-INSERT ROWID reselect (no Executing ROWID queryline in logs), and the session’s open-cursor count stays flat — no ORA-01000.
log:
Code:
=== 2025-09-30 00:31:17,018 [ec-4] DEBUG com.isomorphic.sql.SQLDriver - ROWID query returned 1 rows
=== 2025-09-30 00:31:17,018 [ec-4] DEBUG com.isomorphic.sql.SQLDriver - Setting sequence value for field ID to 2027
=== 2025-09-30 00:31:17,018 [ec-4] DEBUG com.isomorphic.sql.SQLDriver - Discovered zero or one generated key via JDBC: {ID=2027}
=== 2025-09-30 00:31:17,018 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - Added JDBC-generated values to the list of primaryKeys
=== 2025-09-30 00:31:17,018 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - cache sync skipped by dsRequest.setSkipCacheSync() directive - setting invalidateCache: true on response
=== 2025-09-30 00:31:17,018 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - add operation affected 1 rows
=== 2025-09-30 00:31:17,018 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - cache sync skipped by dsRequest.setSkipCacheSync() directive - setting invalidateCache: true on response
=== 2025-09-30 00:31:17,019 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - In getSchemaName(); for DataSource R_C2544BDB_51D7_4759_8B73_1AAFCEDAB29B_WLW_DRMREPO_ORAPRXM_foredit
=== 2025-09-30 00:31:17,019 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - 'schema' retrieved from config is 'MSDATA'
=== 2025-09-30 00:31:17,021 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - Setting DSRequest as being part of a transaction on connection 1604855004
=== 2025-09-30 00:31:17,021 [ec-4] INFO com.isomorphic.sql.SQLDriver - Executing SQL query on 'C_DC7B902C_1DB4_44D4_83C3_5E6678C55AD2_DRMREPO_ORAPRXM' using connection '1604855004': INSERT INTO MSDATA.OSOBA (IMIE, NAZWISKO, WIEK) VALUES ('Adam', 'Mazur', 46)
wrz 30, 2025 12:31:16 AM oracle.jdbc.driver.OraclePreparedStatement executeLargeUpdate
INFO:
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.T4CPreparedStatement initializeOall8
INFO: cursorId=0
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.T4C8Oall doOALL
INFO: OALL8 options=1 065, cursor=297.
=== 2025-09-30 00:31:17,059 [ec-4] DEBUG com.isomorphic.sql.SQLDriver - Found 1 sequence(s)/autoGenerated PK field(s): [ID]
=== 2025-09-30 00:31:17,059 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - DataSource 388 acquired SQLDriver instance 358869665 during initialization
=== 2025-09-30 00:31:17,059 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - In getSchemaName(); for DataSource R_C2544BDB_51D7_4759_8B73_1AAFCEDAB29B_WLW_DRMREPO_ORAPRXM_foredit
=== 2025-09-30 00:31:17,059 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - 'schema' retrieved from config is 'MSDATA'
=== 2025-09-30 00:31:17,061 [ec-4] DEBUG com.isomorphic.sql.SQLDriver - Executing ROWID query: SELECT OSOBA.ID, OSOBA.IMIE, OSOBA.NAZWISKO, OSOBA.WIEK FROM MSDATA.OSOBA WHERE ROWID = 'AAAV0mAAMAACeywAAg'
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.OracleStatement executeQuery
INFO: null
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.T4CStatement initializeOall8
INFO: cursorId=0
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.T4C8Oall doOALL
INFO: OALL8 options=32 801, cursor=296.
(...)
INFO: OALL8 options=32 801, cursor=297.
(...)
INFO: OALL8 options=1 065, cursor=299.
(...)
INFO: OALL8 options=32 801, cursor=298.
(...)
INFO: OALL8 options=1 065, cursor=300.
=== 2025-09-30 00:31:17,531 [ec-4] DEBUG com.isomorphic.sql.SQLDriver - Found 1 sequence(s)/autoGenerated PK field(s): [ID]
=== 2025-09-30 00:31:17,532 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - DataSource 391 acquired SQLDriver instance 2089693649 during initialization
=== 2025-09-30 00:31:17,532 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - In getSchemaName(); for DataSource R_C2544BDB_51D7_4759_8B73_1AAFCEDAB29B_WLW_DRMREPO_ORAPRXM_foredit
=== 2025-09-30 00:31:17,532 [ec-4] DEBUG com.isomorphic.sql.SQLDataSource - 'schema' retrieved from config is 'MSDATA'
=== 2025-09-30 00:31:17,534 [ec-4] DEBUG com.isomorphic.sql.SQLDriver - Executing ROWID query: SELECT OSOBA.ID, OSOBA.IMIE, OSOBA.NAZWISKO, OSOBA.WIEK FROM MSDATA.OSOBA WHERE ROWID = 'AAAV0mAAMAACeywAAj'
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.OracleStatement executeQuery
INFO: null
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.T4CStatement initializeOall8
INFO: cursorId=0
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.T4CMAREngineNIO prepareForUnmarshall
INFO: Break received from server. Responding with reset...
wrz 30, 2025 12:31:17 AM oracle.net.ns.NSProtocolNIO sendReset
INFO: SO_TIMEOUT interrupt timer cancelled null
wrz 30, 2025 12:31:17 AM oracle.net.ns.NSProtocolNIO sendMarker
INFO: Sending break marker, SessionTraceId = 5FA824DC
wrz 30, 2025 12:31:17 AM oracle.jdbc.driver.OracleStatement executeQuery
INFO: null
java.sql.SQLException: ORA-00604: An error occurred while processing a recursive SQL statement
ORA-01000: maximum open cursors exceeded
Code:
CREATE TABLE msdata.osoba (
id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1 INCREMENT BY 1),
imie VARCHAR2(50 CHAR) NOT NULL,
nazwisko VARCHAR2(80 CHAR) NOT NULL,
wiek NUMBER(3,0),
CONSTRAINT osoba_pk PRIMARY KEY (id)
);
INSERT INTO osoba (imie, nazwisko, wiek) VALUES ('Jan', 'Kowalski', 25);
INSERT INTO osoba (imie, nazwisko, wiek) VALUES ('Anna', 'Nowak', 32);
INSERT INTO osoba (imie, nazwisko, wiek) VALUES ('Piotr', 'Wisniewski', 39);
INSERT INTO osoba (imie, nazwisko, wiek) VALUES ('Kasia', 'Wojcik', 46);
INSERT INTO osoba (imie, nazwisko, wiek) VALUES ('Tomasz', 'Kowalczyk', 53);
INSERT INTO osoba (imie, nazwisko, wiek) VALUES ('Ewa', 'Lewandowski', 60);
Code:
<DataSource ID="R_C2544BDB_51D7_4759_8B73_1AAFCEDAB29B" allowAdvancedCriteria="true" dbName ="C_DC7B902C_1DB4_44D4_83C3_5E6678C55AD2" dbType="oracle" sequenceMode="jdbcDriver" serverType="sql" tableName="OSOBA" >
<fields>
<field canEdit="true" canSave="true" escapeHTML="true" implicitSequence="true" name="ID" primaryKey="true" type="sequence"/>
<field canEdit="true" canSave="true" escapeHTML="true" length="50" name="IMIE" type="text"/>
<field canEdit="true" canSave="true" escapeHTML="true" length="80" name="NAZWISKO" type="text"/>
<field canEdit="true" canSave="true" escapeHTML="true" name="WIEK" type="integer"/>
</fields>
</DataSource>
ORACLE logging:
Code:
-Doracle.jdbc.diagnostic.enableLogging=true -Doracle.jdbc.diagnostic.permitSensitiveDiagnostics=true -Doracle.jdbc.diagnostic.enableSensitiveDiagnostics=true -Djava.util.logging.config.file=OracleLog.properties
Code:
handlers = java.util.logging.ConsoleHandler oracle.jdbc.level = ALL java.util.logging.ConsoleHandler.level = ALL java.util.logging.ConsoleHandler.formatter = oracle.jdbc.diagnostics.OracleSimpleFormatter
Comment