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