Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/sql/BatchUpdateException.java
38829 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.sql;2627import java.io.IOException;28import java.io.InvalidObjectException;29import java.io.ObjectInputStream;30import java.io.ObjectOutputStream;31import java.util.Arrays;3233/**34* The subclass of {@link SQLException} thrown when an error35* occurs during a batch update operation. In addition to the36* information provided by {@link SQLException}, a37* <code>BatchUpdateException</code> provides the update38* counts for all commands that were executed successfully during the39* batch update, that is, all commands that were executed before the error40* occurred. The order of elements in an array of update counts41* corresponds to the order in which commands were added to the batch.42* <P>43* After a command in a batch update fails to execute properly44* and a <code>BatchUpdateException</code> is thrown, the driver45* may or may not continue to process the remaining commands in46* the batch. If the driver continues processing after a failure,47* the array returned by the method48* <code>BatchUpdateException.getUpdateCounts</code> will have49* an element for every command in the batch rather than only50* elements for the commands that executed successfully before51* the error. In the case where the driver continues processing52* commands, the array element for any command53* that failed is <code>Statement.EXECUTE_FAILED</code>.54* <P>55* A JDBC driver implementation should use56* the constructor {@code BatchUpdateException(String reason, String SQLState,57* int vendorCode, long []updateCounts,Throwable cause) } instead of58* constructors that take {@code int[]} for the update counts to avoid the59* possibility of overflow.60* <p>61* If {@code Statement.executeLargeBatch} method is invoked it is recommended that62* {@code getLargeUpdateCounts} be called instead of {@code getUpdateCounts}63* in order to avoid a possible overflow of the integer update count.64* @since 1.265*/6667public class BatchUpdateException extends SQLException {6869/**70* Constructs a <code>BatchUpdateException</code> object initialized with a given71* <code>reason</code>, <code>SQLState</code>, <code>vendorCode</code> and72* <code>updateCounts</code>.73* The <code>cause</code> is not initialized, and may subsequently be74* initialized by a call to the75* {@link Throwable#initCause(java.lang.Throwable)} method.76* <p>77* <strong>Note:</strong> There is no validation of {@code updateCounts} for78* overflow and because of this it is recommended that you use the constructor79* {@code BatchUpdateException(String reason, String SQLState,80* int vendorCode, long []updateCounts,Throwable cause) }.81* </p>82* @param reason a description of the error83* @param SQLState an XOPEN or SQL:2003 code identifying the exception84* @param vendorCode an exception code used by a particular85* database vendor86* @param updateCounts an array of <code>int</code>, with each element87* indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or88* <code>Statement.EXECUTE_FAILED</code> for each SQL command in89* the batch for JDBC drivers that continue processing90* after a command failure; an update count or91* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch92* prior to the failure for JDBC drivers that stop processing after a command93* failure94* @since 1.295* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],96* java.lang.Throwable)97*/98public BatchUpdateException( String reason, String SQLState, int vendorCode,99int[] updateCounts ) {100super(reason, SQLState, vendorCode);101this.updateCounts = (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length);102this.longUpdateCounts = (updateCounts == null) ? null : copyUpdateCount(updateCounts);103}104105/**106* Constructs a <code>BatchUpdateException</code> object initialized with a given107* <code>reason</code>, <code>SQLState</code> and108* <code>updateCounts</code>.109* The <code>cause</code> is not initialized, and may subsequently be110* initialized by a call to the111* {@link Throwable#initCause(java.lang.Throwable)} method. The vendor code112* is initialized to 0.113* <p>114* <strong>Note:</strong> There is no validation of {@code updateCounts} for115* overflow and because of this it is recommended that you use the constructor116* {@code BatchUpdateException(String reason, String SQLState,117* int vendorCode, long []updateCounts,Throwable cause) }.118* </p>119* @param reason a description of the exception120* @param SQLState an XOPEN or SQL:2003 code identifying the exception121* @param updateCounts an array of <code>int</code>, with each element122* indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or123* <code>Statement.EXECUTE_FAILED</code> for each SQL command in124* the batch for JDBC drivers that continue processing125* after a command failure; an update count or126* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch127* prior to the failure for JDBC drivers that stop processing after a command128* failure129* @since 1.2130* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],131* java.lang.Throwable)132*/133public BatchUpdateException(String reason, String SQLState,134int[] updateCounts) {135this(reason, SQLState, 0, updateCounts);136}137138/**139* Constructs a <code>BatchUpdateException</code> object initialized with a given140* <code>reason</code> and <code>updateCounts</code>.141* The <code>cause</code> is not initialized, and may subsequently be142* initialized by a call to the143* {@link Throwable#initCause(java.lang.Throwable)} method. The144* <code>SQLState</code> is initialized to <code>null</code>145* and the vendor code is initialized to 0.146* <p>147* <strong>Note:</strong> There is no validation of {@code updateCounts} for148* overflow and because of this it is recommended that you use the constructor149* {@code BatchUpdateException(String reason, String SQLState,150* int vendorCode, long []updateCounts,Throwable cause) }.151* </p>152* @param reason a description of the exception153* @param updateCounts an array of <code>int</code>, with each element154* indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or155* <code>Statement.EXECUTE_FAILED</code> for each SQL command in156* the batch for JDBC drivers that continue processing157* after a command failure; an update count or158* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch159* prior to the failure for JDBC drivers that stop processing after a command160* failure161* @since 1.2162* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],163* java.lang.Throwable)164*/165public BatchUpdateException(String reason, int[] updateCounts) {166this(reason, null, 0, updateCounts);167}168169/**170* Constructs a <code>BatchUpdateException</code> object initialized with a given171* <code>updateCounts</code>.172* initialized by a call to the173* {@link Throwable#initCause(java.lang.Throwable)} method. The <code>reason</code>174* and <code>SQLState</code> are initialized to null and the vendor code175* is initialized to 0.176* <p>177* <strong>Note:</strong> There is no validation of {@code updateCounts} for178* overflow and because of this it is recommended that you use the constructor179* {@code BatchUpdateException(String reason, String SQLState,180* int vendorCode, long []updateCounts,Throwable cause) }.181* </p>182* @param updateCounts an array of <code>int</code>, with each element183* indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or184* <code>Statement.EXECUTE_FAILED</code> for each SQL command in185* the batch for JDBC drivers that continue processing186* after a command failure; an update count or187* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch188* prior to the failure for JDBC drivers that stop processing after a command189* failure190* @since 1.2191* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],192* java.lang.Throwable)193*/194public BatchUpdateException(int[] updateCounts) {195this(null, null, 0, updateCounts);196}197198/**199* Constructs a <code>BatchUpdateException</code> object.200* The <code>reason</code>, <code>SQLState</code> and <code>updateCounts</code>201* are initialized to <code>null</code> and the vendor code is initialized to 0.202* The <code>cause</code> is not initialized, and may subsequently be203* initialized by a call to the204* {@link Throwable#initCause(java.lang.Throwable)} method.205* <p>206*207* @since 1.2208* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],209* java.lang.Throwable)210*/211public BatchUpdateException() {212this(null, null, 0, null);213}214215/**216* Constructs a <code>BatchUpdateException</code> object initialized with217* a given <code>cause</code>.218* The <code>SQLState</code> and <code>updateCounts</code>219* are initialized220* to <code>null</code> and the vendor code is initialized to 0.221* The <code>reason</code> is initialized to <code>null</code> if222* <code>cause==null</code> or to <code>cause.toString()</code> if223* <code>cause!=null</code>.224* @param cause the underlying reason for this <code>SQLException</code>225* (which is saved for later retrieval by the <code>getCause()</code> method);226* may be null indicating the cause is non-existent or unknown.227* @since 1.6228* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],229* java.lang.Throwable)230*/231public BatchUpdateException(Throwable cause) {232this((cause == null ? null : cause.toString()), null, 0, (int[])null, cause);233}234235/**236* Constructs a <code>BatchUpdateException</code> object initialized with a237* given <code>cause</code> and <code>updateCounts</code>.238* The <code>SQLState</code> is initialized239* to <code>null</code> and the vendor code is initialized to 0.240* The <code>reason</code> is initialized to <code>null</code> if241* <code>cause==null</code> or to <code>cause.toString()</code> if242* <code>cause!=null</code>.243* <p>244* <strong>Note:</strong> There is no validation of {@code updateCounts} for245* overflow and because of this it is recommended that you use the constructor246* {@code BatchUpdateException(String reason, String SQLState,247* int vendorCode, long []updateCounts,Throwable cause) }.248* </p>249* @param updateCounts an array of <code>int</code>, with each element250* indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or251* <code>Statement.EXECUTE_FAILED</code> for each SQL command in252* the batch for JDBC drivers that continue processing253* after a command failure; an update count or254* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch255* prior to the failure for JDBC drivers that stop processing after a command256* failure257* @param cause the underlying reason for this <code>SQLException</code>258* (which is saved for later retrieval by the <code>getCause()</code> method); may be null indicating259* the cause is non-existent or unknown.260* @since 1.6261* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],262* java.lang.Throwable)263*/264public BatchUpdateException(int []updateCounts , Throwable cause) {265this((cause == null ? null : cause.toString()), null, 0, updateCounts, cause);266}267268/**269* Constructs a <code>BatchUpdateException</code> object initialized with270* a given <code>reason</code>, <code>cause</code>271* and <code>updateCounts</code>. The <code>SQLState</code> is initialized272* to <code>null</code> and the vendor code is initialized to 0.273* <p>274* <strong>Note:</strong> There is no validation of {@code updateCounts} for275* overflow and because of this it is recommended that you use the constructor276* {@code BatchUpdateException(String reason, String SQLState,277* int vendorCode, long []updateCounts,Throwable cause) }.278* </p>279* @param reason a description of the exception280* @param updateCounts an array of <code>int</code>, with each element281*indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or282* <code>Statement.EXECUTE_FAILED</code> for each SQL command in283* the batch for JDBC drivers that continue processing284* after a command failure; an update count or285* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch286* prior to the failure for JDBC drivers that stop processing after a command287* failure288* @param cause the underlying reason for this <code>SQLException</code> (which is saved for later retrieval by the <code>getCause()</code> method);289* may be null indicating290* the cause is non-existent or unknown.291* @since 1.6292* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],293* java.lang.Throwable)294*/295public BatchUpdateException(String reason, int []updateCounts, Throwable cause) {296this(reason, null, 0, updateCounts, cause);297}298299/**300* Constructs a <code>BatchUpdateException</code> object initialized with301* a given <code>reason</code>, <code>SQLState</code>,<code>cause</code>, and302* <code>updateCounts</code>. The vendor code is initialized to 0.303*304* @param reason a description of the exception305* @param SQLState an XOPEN or SQL:2003 code identifying the exception306* @param updateCounts an array of <code>int</code>, with each element307* indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or308* <code>Statement.EXECUTE_FAILED</code> for each SQL command in309* the batch for JDBC drivers that continue processing310* after a command failure; an update count or311* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch312* prior to the failure for JDBC drivers that stop processing after a command313* failure314* <p>315* <strong>Note:</strong> There is no validation of {@code updateCounts} for316* overflow and because of this it is recommended that you use the constructor317* {@code BatchUpdateException(String reason, String SQLState,318* int vendorCode, long []updateCounts,Throwable cause) }.319* </p>320* @param cause the underlying reason for this <code>SQLException</code>321* (which is saved for later retrieval by the <code>getCause()</code> method);322* may be null indicating323* the cause is non-existent or unknown.324* @since 1.6325* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],326* java.lang.Throwable)327*/328public BatchUpdateException(String reason, String SQLState,329int []updateCounts, Throwable cause) {330this(reason, SQLState, 0, updateCounts, cause);331}332333/**334* Constructs a <code>BatchUpdateException</code> object initialized with335* a given <code>reason</code>, <code>SQLState</code>, <code>vendorCode</code>336* <code>cause</code> and <code>updateCounts</code>.337*338* @param reason a description of the error339* @param SQLState an XOPEN or SQL:2003 code identifying the exception340* @param vendorCode an exception code used by a particular341* database vendor342* @param updateCounts an array of <code>int</code>, with each element343*indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or344* <code>Statement.EXECUTE_FAILED</code> for each SQL command in345* the batch for JDBC drivers that continue processing346* after a command failure; an update count or347* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch348* prior to the failure for JDBC drivers that stop processing after a command349* failure350* <p>351* <strong>Note:</strong> There is no validation of {@code updateCounts} for352* overflow and because of this it is recommended that you use the constructor353* {@code BatchUpdateException(String reason, String SQLState,354* int vendorCode, long []updateCounts,Throwable cause) }.355* </p>356* @param cause the underlying reason for this <code>SQLException</code> (which is saved for later retrieval by the <code>getCause()</code> method);357* may be null indicating358* the cause is non-existent or unknown.359* @since 1.6360* @see #BatchUpdateException(java.lang.String, java.lang.String, int, long[],361* java.lang.Throwable)362*/363public BatchUpdateException(String reason, String SQLState, int vendorCode,364int []updateCounts,Throwable cause) {365super(reason, SQLState, vendorCode, cause);366this.updateCounts = (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length);367this.longUpdateCounts = (updateCounts == null) ? null : copyUpdateCount(updateCounts);368}369370/**371* Retrieves the update count for each update statement in the batch372* update that executed successfully before this exception occurred.373* A driver that implements batch updates may or may not continue to374* process the remaining commands in a batch when one of the commands375* fails to execute properly. If the driver continues processing commands,376* the array returned by this method will have as many elements as377* there are commands in the batch; otherwise, it will contain an378* update count for each command that executed successfully before379* the <code>BatchUpdateException</code> was thrown.380*<P>381* The possible return values for this method were modified for382* the Java 2 SDK, Standard Edition, version 1.3. This was done to383* accommodate the new option of continuing to process commands384* in a batch update after a <code>BatchUpdateException</code> object385* has been thrown.386*387* @return an array of <code>int</code> containing the update counts388* for the updates that were executed successfully before this error389* occurred. Or, if the driver continues to process commands after an390* error, one of the following for every command in the batch:391* <OL>392* <LI>an update count393* <LI><code>Statement.SUCCESS_NO_INFO</code> to indicate that the command394* executed successfully but the number of rows affected is unknown395* <LI><code>Statement.EXECUTE_FAILED</code> to indicate that the command396* failed to execute successfully397* </OL>398* @since 1.3399* @see #getLargeUpdateCounts()400*/401public int[] getUpdateCounts() {402return (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length);403}404405/**406* Constructs a <code>BatchUpdateException</code> object initialized with407* a given <code>reason</code>, <code>SQLState</code>, <code>vendorCode</code>408* <code>cause</code> and <code>updateCounts</code>.409* <p>410* This constructor should be used when the returned update count may exceed411* {@link Integer#MAX_VALUE}.412* <p>413* @param reason a description of the error414* @param SQLState an XOPEN or SQL:2003 code identifying the exception415* @param vendorCode an exception code used by a particular416* database vendor417* @param updateCounts an array of <code>long</code>, with each element418*indicating the update count, <code>Statement.SUCCESS_NO_INFO</code> or419* <code>Statement.EXECUTE_FAILED</code> for each SQL command in420* the batch for JDBC drivers that continue processing421* after a command failure; an update count or422* <code>Statement.SUCCESS_NO_INFO</code> for each SQL command in the batch423* prior to the failure for JDBC drivers that stop processing after a command424* failure425* @param cause the underlying reason for this <code>SQLException</code>426* (which is saved for later retrieval by the <code>getCause()</code> method);427* may be null indicating the cause is non-existent or unknown.428* @since 1.8429*/430public BatchUpdateException(String reason, String SQLState, int vendorCode,431long []updateCounts,Throwable cause) {432super(reason, SQLState, vendorCode, cause);433this.longUpdateCounts = (updateCounts == null) ? null : Arrays.copyOf(updateCounts, updateCounts.length);434this.updateCounts = (longUpdateCounts == null) ? null : copyUpdateCount(longUpdateCounts);435}436437/**438* Retrieves the update count for each update statement in the batch439* update that executed successfully before this exception occurred.440* A driver that implements batch updates may or may not continue to441* process the remaining commands in a batch when one of the commands442* fails to execute properly. If the driver continues processing commands,443* the array returned by this method will have as many elements as444* there are commands in the batch; otherwise, it will contain an445* update count for each command that executed successfully before446* the <code>BatchUpdateException</code> was thrown.447* <p>448* This method should be used when {@code Statement.executeLargeBatch} is449* invoked and the returned update count may exceed {@link Integer#MAX_VALUE}.450* <p>451* @return an array of <code>long</code> containing the update counts452* for the updates that were executed successfully before this error453* occurred. Or, if the driver continues to process commands after an454* error, one of the following for every command in the batch:455* <OL>456* <LI>an update count457* <LI><code>Statement.SUCCESS_NO_INFO</code> to indicate that the command458* executed successfully but the number of rows affected is unknown459* <LI><code>Statement.EXECUTE_FAILED</code> to indicate that the command460* failed to execute successfully461* </OL>462* @since 1.8463*/464public long[] getLargeUpdateCounts() {465return (longUpdateCounts == null) ? null :466Arrays.copyOf(longUpdateCounts, longUpdateCounts.length);467}468469/**470* The array that describes the outcome of a batch execution.471* @serial472* @since 1.2473*/474private int[] updateCounts;475476/*477* Starting with Java SE 8, JDBC has added support for returning an update478* count > Integer.MAX_VALUE. Because of this the following changes were made479* to BatchUpdateException:480* <ul>481* <li>Add field longUpdateCounts</li>482* <li>Add Constructorr which takes long[] for update counts</li>483* <li>Add getLargeUpdateCounts method</li>484* </ul>485* When any of the constructors are called, the int[] and long[] updateCount486* fields are populated by copying the one array to each other.487*488* As the JDBC driver passes in the updateCounts, there has always been the489* possiblity for overflow and BatchUpdateException does not need to account490* for that, it simply copies the arrays.491*492* JDBC drivers should always use the constructor that specifies long[] and493* JDBC application developers should call getLargeUpdateCounts.494*/495496/**497* The array that describes the outcome of a batch execution.498* @serial499* @since 1.8500*/501private long[] longUpdateCounts;502503private static final long serialVersionUID = 5977529877145521757L;504505/*506* Utility method to copy int[] updateCount to long[] updateCount507*/508private static long[] copyUpdateCount(int[] uc) {509long[] copy = new long[uc.length];510for(int i= 0; i< uc.length; i++) {511copy[i] = uc[i];512}513return copy;514}515516/*517* Utility method to copy long[] updateCount to int[] updateCount.518* No checks for overflow will be done as it is expected a user will call519* getLargeUpdateCounts.520*/521private static int[] copyUpdateCount(long[] uc) {522int[] copy = new int[uc.length];523for(int i= 0; i< uc.length; i++) {524copy[i] = (int) uc[i];525}526return copy;527}528/**529* readObject is called to restore the state of the530* {@code BatchUpdateException} from a stream.531*/532private void readObject(ObjectInputStream s)533throws IOException, ClassNotFoundException {534535ObjectInputStream.GetField fields = s.readFields();536int[] tmp = (int[])fields.get("updateCounts", null);537long[] tmp2 = (long[])fields.get("longUpdateCounts", null);538if(tmp != null && tmp2 != null && tmp.length != tmp2.length)539throw new InvalidObjectException("update counts are not the expected size");540if (tmp != null)541updateCounts = tmp.clone();542if (tmp2 != null)543longUpdateCounts = tmp2.clone();544if(updateCounts == null && longUpdateCounts != null)545updateCounts = copyUpdateCount(longUpdateCounts);546if(longUpdateCounts == null && updateCounts != null)547longUpdateCounts = copyUpdateCount(updateCounts);548549}550551/**552* writeObject is called to save the state of the {@code BatchUpdateException}553* to a stream.554*/555private void writeObject(ObjectOutputStream s)556throws IOException, ClassNotFoundException {557558ObjectOutputStream.PutField fields = s.putFields();559fields.put("updateCounts", updateCounts);560fields.put("longUpdateCounts", longUpdateCounts);561s.writeFields();562}563}564565566