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