Hi, For JDBC 4.2, I am adding methods to allow for larger update counts (request from JDBC driver vendors) and because of this I have to tweak BatchUpdateException
The Statement interface has the method int[] executeBatch() I am planning to add long[] executeLargeBatch(). To accomodate this change, I also need to add a new field and the method getLargeUpdateCount to BatchUpdateException. I have exchanged emails on this with Alan and he indicated that the changes seemed reasonable but to send a general email out to see if anything was missed from the serialization perspective. I have added JDBC Unit tests to validate that the serialization/deserialization works between JDBC 4.1 and JDBC 4.2 and they run without a problem. Best Lance new-host-2:sql lanceandersen$ diff BatchUpdateException.java ~/NetBeansProjects/JDBC4.2/jdbc4.0/src/java/sql/ 2c2 < * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. --- > * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights > reserved. 27a28,31 > import java.io.IOException; > import java.io.InvalidObjectException; > import java.io.ObjectInputStream; > import java.io.ObjectOutputStream; 83a88 > this.longUpdateCounts = (updateCounts == null) ? null : > copyUpdateCount(updateCounts); 192c197 < this((cause == null ? null : cause.toString()), null, 0, null, cause); --- > this((cause == null ? null : cause.toString()), null, 0, (int[])null, > cause); 295a301 > this.longUpdateCounts = (updateCounts == null) ? null : > copyUpdateCount(updateCounts); 331c337,401 < --- > > /** > * Constructs a <code>BatchUpdateException</code> object initialized with > * a given <code>reason</code>, <code>SQLState</code>, > <code>vendorCode</code> > * <code>cause</code> and <code>updateCounts</code>. > * <p> > * This constructor should be used when the returned update count may exceed > * {@link Integer.MAX_VALUE}. > * <p> > * @param reason a description of the error > * @param SQLState an XOPEN or SQL:2003 code identifying the exception > * @param vendorCode an exception code used by a particular > * database vendor > * @param updateCounts an array of <code>long</code>, with each element > *indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or > * <code>Statement.EXECUTE_FAILED</code> for each SQL command in > * the batch for JDBC drivers that continue processing > * after a command failure; an update count or > * <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch > * prior to the failure for JDBC drivers that stop processing after a > command > * failure > * @param cause the underlying reason for this <code>SQLException</code> > * (which is saved for later retrieval by the <code>getCause()</code> > method); > * may be null indicating the cause is non-existent or unknown. > * @since 1.8 > */ > public BatchUpdateException(String reason, String SQLState, int vendorCode, > long []updateCounts,Throwable cause) { > super(reason, SQLState, vendorCode, cause); > this.longUpdateCounts = (updateCounts == null) ? null : > Arrays.copyOf(updateCounts, updateCounts.length); > this.updateCounts = (longUpdateCounts == null) ? null : > copyUpdateCount(longUpdateCounts); > } > > /** > * Retrieves the update count for each update statement in the batch > * update that executed successfully before this exception occurred. > * A driver that implements batch updates may or may not continue to > * process the remaining commands in a batch when one of the commands > * fails to execute properly. If the driver continues processing commands, > * the array returned by this method will have as many elements as > * there are commands in the batch; otherwise, it will contain an > * update count for each command that executed successfully before > * the <code>BatchUpdateException</code> was thrown. > * <p> > * This method should be used when the returned update count may exceed > * {@link Integer.MAX_VALUE}. > * <p> > * @return an array of <code>long</code> containing the update counts > * for the updates that were executed successfully before this error > * occurred. Or, if the driver continues to process commands after an > * error, one of the following for every command in the batch: > * <OL> > * <LI>an update count > * <LI><code>Statement.SUCCESS_NO_INFO</code> to indicate that the command > * executed successfully but the number of rows affected is unknown > * <LI><code>Statement.EXECUTE_FAILED</code> to indicate that the command > * failed to execute successfully > * </OL> > * @since 1.8 > */ > public long[] getLargeUpdateCounts() { > return (longUpdateCounts == null) ? null : > Arrays.copyOf(longUpdateCounts, longUpdateCounts.length); > } > 337c407,414 < private final int[] updateCounts; --- > private int[] updateCounts; > > /** > * The array that describes the outcome of a batch execution. > * @serial > * @since 1.8 > */ > private long[] longUpdateCounts; 339a417,474 > > /* > * Utility method to copy int[] updateCount to long[] updateCount > */ > private static long[] copyUpdateCount(int[] uc) { > long[] copy = new long[uc.length]; > for(int i= 0; i< uc.length; i++) { > copy[i] = uc[i]; > > } > return copy; > } > > /* > * Utility method to copy int[] updateCount to long[] updateCount > */ > private static int[] copyUpdateCount(long[] uc) { > int[] copy = new int[uc.length]; > for(int i= 0; i< uc.length; i++) { > copy[i] = (int) uc[i]; > } > return copy; > } > /** > * readObject is called to restore the state of the > * {@code BatchUpdateException} from a stream. > */ > private void readObject(ObjectInputStream s) > throws IOException, ClassNotFoundException { > > ObjectInputStream.GetField fields = s.readFields(); > int[] tmp = (int[])fields.get("updateCounts", null); > long[] tmp2 = (long[])fields.get("longUpdateCounts", null); > if(tmp != null && tmp2 != null && tmp.length != tmp2.length) > throw new InvalidObjectException("update counts are not the > expected size"); > if (tmp != null) > updateCounts = tmp.clone(); > if (tmp2 != null) > longUpdateCounts = tmp2.clone(); > if(updateCounts == null && longUpdateCounts != null) > updateCounts = copyUpdateCount(longUpdateCounts); > if(longUpdateCounts == null && updateCounts != null) > longUpdateCounts = copyUpdateCount(updateCounts); > > } > > /** > * writeObject is called to save the state of the {@code > BatchUpdateException} > * to a stream. > */ > private void writeObject(ObjectOutputStream s) > throws IOException, ClassNotFoundException { > > ObjectOutputStream.PutField fields = s.putFields(); > fields.put("updateCounts", updateCounts); > fields.put("longUpdateCounts", longUpdateCounts); > s.writeFields(); > } Lance Andersen| Principal Member of Technical Staff | +1.781.442.2037 Oracle Java Engineering 1 Network Drive Burlington, MA 01803 lance.ander...@oracle.com