src/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java

Print this page

        

@@ -826,57 +826,75 @@
          *         <code>true</code> otherwise
          * @throws SQLException if a database access error occurs
          */
     private boolean insertNewRow(CachedRowSet crs,
         PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException {
-        int i = 0;
-        int icolCount = crs.getMetaData().getColumnCount();
 
         boolean returnVal = false;
-        PreparedStatement pstmtSel = con.prepareStatement(selectCmd,
-                        ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
-        ResultSet rs, rs2 = null;
-        DatabaseMetaData dbmd = con.getMetaData();
-        rs = pstmtSel.executeQuery();
-        String table = crs.getTableName();
-        rs2 = dbmd.getPrimaryKeys(null, null, table);
-        String [] primaryKeys = new String[icolCount];
+
+       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()) {
-            String pkcolname = rs2.getString("COLUMN_NAME");
-            primaryKeys[k] = pkcolname;
+           while (rs2.next()) {
+               primaryKeys[k] = rs2.getString("COLUMN_NAME");
             k++;
         }
 
-        if(rs.next()) {
-            for(int j=0;j<primaryKeys.length;j++) {
-                if(primaryKeys[j] != null) {
-                    if(crs.getObject(primaryKeys[j]) == null){
+           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 crsPK = (crs.getObject(primaryKeys[j])).toString();
-                    String rsPK = (rs.getObject(primaryKeys[j])).toString();
-                    if(crsPK.equals(rsPK)) {
+
+                   String rsPK = rs.getObject(pkName).toString();
+                   if (crsPK.toString().equals(rsPK)) {
                         returnVal = true;
                         this.crsResolve.moveToInsertRow();
-                        for(i = 1; i <= icolCount; i++) {
+                       for (int i = 1; i <= icolCount; i++) {
                             String colname = (rs.getMetaData()).getColumnName(i);
-                            if(colname.equals(primaryKeys[j]))
+                           if (colname.equals(pkName))
                                 this.crsResolve.updateObject(i,rsPK);
                             else
                                 this.crsResolve.updateNull(i);
                         }
                         this.crsResolve.insertRow();
                         this.crsResolve.moveToCurrentRow();
                     }
                 }
             }
-        }
-        if(returnVal)
+
+           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 {

@@ -886,29 +904,30 @@
 
              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(i = 1; i <= icolCount; i++) {
+               for (int i = 1; i <= icolCount; i++) {
                this.crsResolve.updateNull(i);
             }
 
             this.crsResolve.insertRow();
             this.crsResolve.moveToCurrentRow();
 
             return true;
         }
     }
+   }
 
 /**
  * Deletes the row in the underlying data source that corresponds to
  * a row that has been deleted in the given <code> CachedRowSet</code> object
  * and returns <code>false</code> if the deletion was successful.

@@ -1435,6 +1454,27 @@
         }
 
     }
 
     static final long serialVersionUID =-8506030970299413976L;
+
+    /**
+     * Validate whether the Primary Key is known to the CachedRowSet.  If it is
+     * not, it is an auto-generated key
+     * @param pk - Primary Key to validate
+     * @param rsmd - ResultSetMetadata for the RowSet
+     * @return true if found, false otherwise (auto generated key)
+     */
+    private boolean isPKNameValid(String pk, ResultSetMetaData rsmd) throws SQLException {
+        boolean isValid = false;
+        int cols = rsmd.getColumnCount();
+        for(int i = 1; i<= cols; i++) {
+            String colName = rsmd.getColumnClassName(i);
+            if(colName.equalsIgnoreCase(pk)) {
+                isValid = true;
+                break;
+            }
+        }   
+        
+        return isValid;
+    }
 }