使用Oracle Thin JDBC执行PreparedStatement触发AssertionError求助
Yep, this is a known bug in the ojdbc7 thin driver—it pops up specifically when you reuse the same PreparedStatement instance to alternate between setting null values (via setNull) and non-null values (like setString).
What's causing this?
The error stems from a faulty assertion check in the driver's internal buffer compression logic (OraclePreparedStatement.compressLastBoundData). When you switch between null and non-null bindings, the driver miscalculates internal offset values, triggering the AssertionError you're seeing. This only happens when JVM assertions are enabled (via the -ea flag); if assertions are off, you won't hit the error, but the underlying logic issue is still present. It also doesn't depend on the Oracle DB version—like you noticed, it shows up in both 11.2 and 12.1.
Fixes/workarounds you can try:
Upgrade your JDBC driver
This is the cleanest solution. Oracle fixed this bug in later driver versions, so moving to ojdbc8 (or newer, like ojdbc11) will eliminate the issue entirely.Disable assertions for Oracle's JDBC driver
If you can't upgrade right away, you can disable assertions specifically for the driver classes by adding this JVM argument when launching your app:-da:oracle.jdbc.driverThis suppresses the assertion error without affecting assertions in other parts of your code.
Recreate the PreparedStatement for each execution
While this has a minor performance cost, creating a newPreparedStatementinstance for every insert avoids reusing the same buffer that's causing the offset miscalculation. Here's a modified version of your code using this approach (try-with-resources ensures proper cleanup):private void insertRows(String tableName) throws SQLException { String insertSQL = "INSERT INTO " + tableName + " (objectid, attributeid, sequence, value) VALUES (?, ?, ?, ?)"; // Insert first 3 rows long objId = 700; long attrId = 701; int seq = 1; // Row 1 (non-null) try (PreparedStatement stmt = m_Conn.prepareStatement(insertSQL)) { stmt.setLong(1, objId); stmt.setLong(2, attrId); stmt.setInt(3, seq++); stmt.setString(4, "Foo"); stmt.execute(); } // Row 2 (null) try (PreparedStatement stmt = m_Conn.prepareStatement(insertSQL)) { stmt.setLong(1, objId); stmt.setLong(2, attrId); stmt.setInt(3, seq++); stmt.setNull(4, Types.VARCHAR); stmt.execute(); } // Row 3 (null) try (PreparedStatement stmt = m_Conn.prepareStatement(insertSQL)) { stmt.setLong(1, objId); stmt.setLong(2, attrId); stmt.setInt(3, seq++); stmt.setNull(4, Types.VARCHAR); stmt.execute(); } // Insert next 2 rows with new IDs objId = 800; attrId = 801; seq = 1; // Row 1 (null) try (PreparedStatement stmt = m_Conn.prepareStatement(insertSQL)) { stmt.setLong(1, objId); stmt.setLong(2, attrId); stmt.setInt(3, seq++); stmt.setNull(4, Types.VARCHAR); stmt.execute(); } // Row 2 (non-null) try (PreparedStatement stmt = m_Conn.prepareStatement(insertSQL)) { stmt.setLong(1, objId); stmt.setLong(2, attrId); stmt.setInt(3, seq++); stmt.setString(4, "Bar"); stmt.execute(); } System.out.println("Inserts were successful"); }
All of these approaches should resolve the AssertionError you're hitting.
内容的提问来源于stack exchange,提问作者Oskar Wetterstein

