Review request for 7145913 CachedRowSetSwriter.insertNewRow() throws SQLException
David Schlosnagle
schlosna at gmail.com
Thu May 31 19:10:34 UTC 2012
On Thu, May 31, 2012 at 1:50 PM, Lance Andersen - Oracle
<Lance.Andersen at oracle.com> wrote:
> Hi,
>
> Looking for a reviewer for 7145913. This addresses an issue with where a SQLException could be thrown when writing a row back with an auto-incremented column on some databases.
>
> Webrev is http://cr.openjdk.java.net/~lancea/7145913/webrev.00/. RowSet TCK, sqe tests and unit tests all pass with this fix.
Hi Lance,
I had a few quick comments:
* Do you need the multiple calls to CachedResultSet.getObject for the primary
key, or would it be worthwhile to store the result in a local variable?
* This seems to be pre-existing before your changes, but the PreparedStatement
pstmtSel and ResultSet rs, rs2 used within the insertNewRow method are never
closed, which could lead to resource leaks.
* Minor nit, the indentation in this file seems off, especially for the method
JavaDoc.
I've included a minor cleanup below of the insertNewRow method using
try-with-resources.
Thanks,
Dave
/**
* Inserts a row that has been inserted into the given
* <code>CachedRowSet</code> object into the data source from which
* the rowset is derived, returning <code>false</code> if the insertion
* was successful.
*
* @param crs the <code>CachedRowSet</code> object that has had a
row inserted
* and to whose underlying data source the row will be inserted
* @param pstmt the <code>PreparedStatement</code> object that will be used
* to execute the insertion
* @return <code>false</code> to indicate that the insertion was successful;
* <code>true</code> otherwise
* @throws SQLException if a database access error occurs
*/
private boolean insertNewRow(CachedRowSet crs,
PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException {
boolean returnVal = false;
try (PreparedStatement pstmtSel = con.prepareStatement(selectCmd,
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = pstmtSel.executeQuery();
ResultSet rs2 = con.getMetaData().getPrimaryKeys(null, null,
crs.getTableName())
) {
ResultSetMetaData rsmd = crs.getMetaData();
int icolCount = rsmd.getColumnCount();
String[] primaryKeys = new String[icolCount];
int k = 0;
while (rs2.next()) {
primaryKeys[k] = rs2.getString("COLUMN_NAME");
k++;
}
if (rs.next()) {
for (String pkName : primaryKeys) {
if (!isPKNameValid(pkName, rsmd)) {
/* We came here as one of the the primary keys
* of the table is not present in the cached
* rowset object, it should be an autoincrement column
* and not included while creating CachedRowSet
* Object, proceed to check for other primary keys
*/
continue;
}
Object crsPK = crs.getObject(pkName);
if (crsPK == null) {
/*
* It is possible that the PK is null on some databases
* and will be filled in at insert time (MySQL
for example)
*/
break;
}
String rsPK = rs.getObject(pkName).toString();
if (crsPK.toString().equals(rsPK)) {
returnVal = true;
this.crsResolve.moveToInsertRow();
for (int i = 1; i <= icolCount; i++) {
String colname =
(rs.getMetaData()).getColumnName(i);
if (colname.equals(pkName))
this.crsResolve.updateObject(i,rsPK);
else
this.crsResolve.updateNull(i);
}
this.crsResolve.insertRow();
this.crsResolve.moveToCurrentRow();
}
}
}
if (returnVal) {
return returnVal;
}
try {
int i;
for (i = 1; i <= icolCount; i++) {
Object obj = crs.getObject(i);
if (obj != null) {
pstmt.setObject(i, obj);
} else {
pstmt.setNull(i,crs.getMetaData().getColumnType(i));
}
}
i = pstmt.executeUpdate();
return false;
} catch (SQLException ex) {
/*
* Cursor will come here if executeUpdate fails.
* There can be many reasons why the insertion failed,
* one can be violation of primary key.
* Hence we cannot exactly identify why the insertion failed
* Present the current row as a null row to the user.
**/
this.crsResolve.moveToInsertRow();
for (int i = 1; i <= icolCount; i++) {
this.crsResolve.updateNull(i);
}
this.crsResolve.insertRow();
this.crsResolve.moveToCurrentRow();
return true;
}
}
}
More information about the core-libs-dev
mailing list