Adding field to BatchUpdateException
Joe Darcy
joe.darcy at oracle.com
Mon Nov 26 06:51:43 UTC 2012
Hi Lance,
I don't see an obvious problem with the code, but I strongly suggest
documenting the correctness conditions regarding the updateCounts and
longUpdateCounts fields; I think that would ease reviewing the new
constructors and serialization code.
Cheers,
-Joe
On 11/24/2012 2:05 PM, Lance Andersen - Oracle wrote:
> 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.Andersen at oracle.com
>
>
More information about the core-libs-dev
mailing list