diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java index 55335b7ed..e83c32e97 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java @@ -98,7 +98,6 @@ import org.apache.openjpa.util.GeneralException; import org.apache.openjpa.util.InternalException; import org.apache.openjpa.util.InvalidStateException; import org.apache.openjpa.util.OpenJPAException; -import org.apache.openjpa.util.ReferentialIntegrityException; import org.apache.openjpa.util.Serialization; import org.apache.openjpa.util.StoreException; import org.apache.openjpa.util.UnsupportedException; @@ -150,6 +149,16 @@ public class DBDictionary private static final String ZERO_TIMESTAMP_STR = "'" + new Timestamp(0) + "'"; + public static final List EMPTY_STRING_LIST = Arrays.asList(new String[]{}); + public static final List[] SQL_STATE_CODES = + {EMPTY_STRING_LIST, // 0: Default + Arrays.asList(new String[]{"41000"}), // 1: LOCK + EMPTY_STRING_LIST, // 2: OBJECT_NOT_FOUND + EMPTY_STRING_LIST, // 3: OPTIMISTIC + Arrays.asList(new String[]{"23000"}), // 4: REFERENTIAL_INTEGRITY + EMPTY_STRING_LIST // 5: OBJECT_EXISTS + }; + private static final Localizer _loc = Localizer.forPackage (DBDictionary.class); @@ -4006,12 +4015,31 @@ public class DBDictionary */ public OpenJPAException newStoreException(String msg, SQLException[] causes, Object failed) { - if (causes.length > 0 && "23000".equals(causes[0].getSQLState())) - return new ReferentialIntegrityException(msg). - setFailedObject(failed).setNestedThrowables(causes); + if (causes != null && causes.length > 0) { + OpenJPAException ret = SQLExceptions.narrow(msg, causes[0], this); + ret.setFailedObject(failed).setNestedThrowables(causes); + return ret; + } return new StoreException(msg).setFailedObject(failed). setNestedThrowables(causes); } + + /** + * Gets the list of String, each represents an error that can help + * to narrow down a SQL exception to specific type of StoreException.
+ * For example, error code "23000" represents referential + * integrity violation and hence can be narrowed down to + * {@link ReferentialIntegrityException} rather than more general + * {@link StoreException}.
+ * JDBC Drivers are not uniform in return values of SQLState for the same + * error and hence each database specific Dictionary can specialize.
+ * Default behavior is to return an empty list. + */ + public List/**/ getSQLStates(int exceptionType) { + if (exceptionType>=0 && exceptionType