Java 使用Oracle精简JDBC执行PreparedStatement时的AssertionError
我在使用Oracle的瘦JDBC驱动程序(ojdbc7)的PreparedStatements时遇到了一个奇怪的bug(看起来像是一个bug)。多次执行PreparedStatement时会出现AssertionError,它似乎与设置空绑定值有关 下面是测试代码的摘录,演示了这一点:Java 使用Oracle精简JDBC执行PreparedStatement时的AssertionError,java,oracle,jdbc,Java,Oracle,Jdbc,我在使用Oracle的瘦JDBC驱动程序(ojdbc7)的PreparedStatements时遇到了一个奇怪的bug(看起来像是一个bug)。多次执行PreparedStatement时会出现AssertionError,它似乎与设置空绑定值有关 下面是测试代码的摘录,演示了这一点: private void insertRows(String tableName) throws SQLException { String insertSQL = "IN
private void insertRows(String tableName) throws SQLException
{
String insertSQL =
"INSERT INTO "
+ tableName
+ " (objectid, attributeid, sequence, value)"
+ " VALUES (?, ?, ?, ?)";
PreparedStatement stmt = m_Conn.prepareStatement(insertSQL);
// insert first 3 rows with same objId and attrId
long objId = 700;
long attrId = 701;
int seq = 1;
stmt.setLong(1, objId);
stmt.setLong(2, attrId);
// 1st row (non-null value)
stmt.setInt(3, seq++);
stmt.setString(4, "Foo");
stmt.execute();
// 2nd row (null value)
stmt.setInt(3, seq++);
stmt.setNull(4, Types.VARCHAR);
stmt.execute();
// 3rd row (null value)
stmt.setInt(3, seq++);
stmt.setNull(4, Types.VARCHAR);
stmt.execute();
// insert next 2 rows with new objId and attrId
objId = 800;
attrId = 801;
seq = 1;
stmt.setLong(1, objId);
stmt.setLong(2, attrId);
// 1st row (null value)
stmt.setInt(3, seq++);
stmt.setNull(4, Types.VARCHAR);
stmt.execute();
// 2nd row (non-null value)
stmt.setInt(3, seq++);
stmt.setString(4, "Bar");
stmt.execute(); // this results in an AssertionError
System.out.println("Inserts were successful");
stmt.close();
}
第五次执行PreparedStatement会导致AssertionError:
Expected AssertionError: java.lang.AssertionError: lastOffset: 5 leastOffset: 5 indexOfLeastOffet: 3
java.lang.AssertionError: lastOffset: 5 leastOffset: 5 indexOfLeastOffet: 3
at oracle.jdbc.driver.OraclePreparedStatement.compressLastBoundData(OraclePreparedStatement.java:1902)
at oracle.jdbc.driver.OraclePreparedStatement.setupDbaBindBuffers(OraclePreparedStatement.java:3062)
at oracle.jdbc.driver.OraclePreparedStatement.setupBindBuffers(OraclePreparedStatement.java:3046)
at oracle.jdbc.driver.OraclePreparedStatement.processCompletedBindRow(OraclePreparedStatement.java:2670)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4790)
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:4901)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1385)
at oracle.Dave.Bug912.insertRows(Bug912.java:130)
at oracle.Dave.Bug912.main(Bug912.java:38)
AssertionError仅在绑定值设置的特定组合中出现,并且似乎与空值的设置有关(如果不使用空值,则不会发生错误)。当断言被禁用时也不会发生这种情况(显然)。数据库版本似乎并不重要——我在11.2和12.1中都看到了这一点
以前有人见过这种虫子吗?如果有人感兴趣,我可以附上一个完整的测试用例。您可以尝试
executeUpdate()
与executeUpdate()的结果相同。您使用的是哪个版本的Oracle(请提供完整版本!)以及哪个版本的Oracle JDBC驱动程序(ojdbc7不是一个版本,它表明它是用于Java 7的)。驱动程序版本为:Oracle 12.1.0.2.0 JDBC 4.1,于2014年6月30日星期一用JDK7编译。数据库版本为12.1.0.2.0。您可以尝试executeUpdate()
与executeUpdate()的结果相同。您使用的是哪个Oracle版本(请使用完整版本!)以及哪个版本的Oracle JDBC驱动程序(ojdbc7不是一个版本,它表示它是针对Java 7的)。驱动程序版本是:Oracle 12.1.0.2.0 JDBC 4.1,在Mon_Jun_30_11:30:34_PDT_2014;上使用JDK7编译。数据库版本是12.1.0.2.0