You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by ss...@apache.org on 2008/09/05 22:24:40 UTC
svn commit: r692529 - in /openjpa/branches/0.9.7-r547073:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/
openjpa-kernel/src/main/java/org/apache/openjpa/util/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/
ope...
Author: ssegu
Date: Fri Sep 5 13:24:39 2008
New Revision: 692529
URL: http://svn.apache.org/viewvc?rev=692529&view=rev
Log:
OPENJPA-462
- Narrow StoreException by SQLException.getSQLState()
- Adding SQLState in DerbyDictionary to demonstrate specialization
- Adding a Test case to verify correct exception type
Added:
openjpa/branches/0.9.7-r547073/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/
- copied from r603032, openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/
openjpa/branches/0.9.7-r547073/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/PObject.java
- copied unchanged from r603032, openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/PObject.java
openjpa/branches/0.9.7-r547073/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/TestException.java
- copied unchanged from r603032, openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/exception/TestException.java
Modified:
openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java
openjpa/branches/0.9.7-r547073/openjpa-kernel/src/main/java/org/apache/openjpa/util/ObjectExistsException.java
openjpa/branches/0.9.7-r547073/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
openjpa/branches/0.9.7-r547073/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java
Modified: openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=692529&r1=692528&r2=692529&view=diff
==============================================================================
--- openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original)
+++ openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Fri Sep 5 13:24:39 2008
@@ -94,7 +94,6 @@
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.GeneralException;
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;
@@ -144,6 +143,16 @@
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);
@@ -3778,12 +3787,35 @@
*/
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.<br>
+ * For example, error code <code>"23000"</code> represents referential
+ * integrity violation and hence can be narrowed down to
+ * {@link ReferentialIntegrityException} rather than more general
+ * {@link StoreException}.<br>
+ * JDBC Drivers are not uniform in return values of SQLState for the same
+ * error and hence each database specific Dictionary can specialize.<br>
+ *
+ *
+ * @return an <em>unmodifiable</em> list of Strings representing supposedly
+ * uniform SQL States for a given type of StoreException.
+ * Default behavior is to return an empty list.
+ */
+ public List/*<String>*/ getSQLStates(int exceptionType) {
+ if (exceptionType>=0 && exceptionType<SQL_STATE_CODES.length)
+ return SQL_STATE_CODES[exceptionType];
+ return EMPTY_STRING_LIST;
+ }
/**
* Closes the specified {@link DataSource} and releases any
Modified: openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java
URL: http://svn.apache.org/viewvc/openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java?rev=692529&r1=692528&r2=692529&view=diff
==============================================================================
--- openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java (original)
+++ openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java Fri Sep 5 13:24:39 2008
@@ -20,9 +20,14 @@
import java.sql.DriverManager;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
+
import javax.sql.DataSource;
+import org.apache.openjpa.util.StoreException;
+
/**
* Dictionary for Apache Derby (formerly Cloudscape).
*/
@@ -93,4 +98,26 @@
}
}
}
+
+ /**
+ * Adds extra SQLState code that Derby JDBC Driver uses. In JDBC 4.0,
+ * SQLState will follow either XOPEN or SQL 2003 convention. A compliant
+ * driver can be queries via DatabaseMetaData.getSQLStateType() to detect
+ * the convention type.<br>
+ * This method is overwritten to highlight that a) the SQL State is ideally
+ * uniform across JDBC Drivers but not practically and b) the overwritten
+ * method must crate a new list to return as the super classes list is
+ * unmodifable.
+ */
+ public List getSQLStates(int exceptionType) {
+ List original = super.getSQLStates(exceptionType);
+ if (exceptionType == StoreException.LOCK) {
+ // Can not add new codes to unmodifable list of the super class
+ List newStates = new ArrayList(original);
+ newStates.add("40XL1");
+ return newStates;
+ }
+ return original;
+ }
+
}
Modified: openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java
URL: http://svn.apache.org/viewvc/openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java?rev=692529&r1=692528&r2=692529&view=diff
==============================================================================
--- openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java (original)
+++ openjpa/branches/0.9.7-r547073/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java Fri Sep 5 13:24:39 2008
@@ -23,7 +23,12 @@
import java.util.List;
import org.apache.openjpa.lib.util.Localizer.Message;
+import org.apache.openjpa.util.LockException;
+import org.apache.openjpa.util.ObjectExistsException;
+import org.apache.openjpa.util.ObjectNotFoundException;
import org.apache.openjpa.util.OpenJPAException;
+import org.apache.openjpa.util.OptimisticException;
+import org.apache.openjpa.util.ReferentialIntegrityException;
import org.apache.openjpa.util.StoreException;
/**
@@ -96,7 +101,7 @@
setNestedThrowables(ses);
return dict.newStoreException(msg, ses, failed);
}
-
+
/**
* Returns an array of {@link SQLException} instances for the
* specified exception.
@@ -112,4 +117,32 @@
}
return (SQLException[]) errs.toArray(new SQLException[errs.size()]);
}
+
+ /**
+ * Narrows the given SQLException to a specific type of
+ * {@link StoreException#getSubtype() StoreException} by analyzing the
+ * SQLState code supplied by SQLException. Each database-specific
+ * {@link DBDictionary dictionary} can supply a set of error codes that will
+ * map to a specific specific type of StoreException via
+ * {@link DBDictionary#getSQLStates(int) getSQLStates()} method.
+ * The default behavior is to return generic {@link StoreException
+ * StoreException}.
+ */
+ public static OpenJPAException narrow(String msg, SQLException se,
+ DBDictionary dict) {
+ String e = se.getSQLState();
+ if (dict.getSQLStates(StoreException.LOCK).contains(e))
+ return new LockException(msg);
+ else if (dict.getSQLStates(StoreException.OBJECT_EXISTS).contains(e))
+ return new ObjectExistsException(msg);
+ else if (dict.getSQLStates(StoreException.OBJECT_NOT_FOUND).contains(e))
+ return new ObjectNotFoundException(msg);
+ else if (dict.getSQLStates(StoreException.OPTIMISTIC).contains(e))
+ return new OptimisticException(msg);
+ else if (dict.getSQLStates(StoreException.REFERENTIAL_INTEGRITY)
+ .contains(e))
+ return new ReferentialIntegrityException(msg);
+ else
+ return new StoreException(msg);
+ }
}
Modified: openjpa/branches/0.9.7-r547073/openjpa-kernel/src/main/java/org/apache/openjpa/util/ObjectExistsException.java
URL: http://svn.apache.org/viewvc/openjpa/branches/0.9.7-r547073/openjpa-kernel/src/main/java/org/apache/openjpa/util/ObjectExistsException.java?rev=692529&r1=692528&r2=692529&view=diff
==============================================================================
--- openjpa/branches/0.9.7-r547073/openjpa-kernel/src/main/java/org/apache/openjpa/util/ObjectExistsException.java (original)
+++ openjpa/branches/0.9.7-r547073/openjpa-kernel/src/main/java/org/apache/openjpa/util/ObjectExistsException.java Fri Sep 5 13:24:39 2008
@@ -28,6 +28,10 @@
public class ObjectExistsException
extends StoreException {
+ public ObjectExistsException(String msg) {
+ super(msg);
+ }
+
public ObjectExistsException(Message msg) {
super(msg);
}
Modified: openjpa/branches/0.9.7-r547073/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/branches/0.9.7-r547073/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java?rev=692529&r1=692528&r2=692529&view=diff
==============================================================================
--- openjpa/branches/0.9.7-r547073/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java (original)
+++ openjpa/branches/0.9.7-r547073/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java Fri Sep 5 13:24:39 2008
@@ -167,4 +167,13 @@
ClassMetaData meta = OpenJPAPersistence.getMetaData(emf, c);
return (meta == null) ? null : meta.getTypeAlias();
}
+
+ public static void assertNotEquals(Object o1, Object o2) {
+ if (o1 == o2)
+ fail("expected args to be different; were the same instance.");
+ else if (o1 == null || o2 == null)
+ return;
+ else if (o1.equals(o2))
+ fail("expected args to be different; compared equal.");
+ }
}
Modified: openjpa/branches/0.9.7-r547073/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java
URL: http://svn.apache.org/viewvc/openjpa/branches/0.9.7-r547073/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java?rev=692529&r1=692528&r2=692529&view=diff
==============================================================================
--- openjpa/branches/0.9.7-r547073/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java (original)
+++ openjpa/branches/0.9.7-r547073/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceExceptions.java Fri Sep 5 13:24:39 2008
@@ -146,6 +146,7 @@
getFailedObject(ke), ke.isFatal());
break;
case StoreException.OPTIMISTIC:
+ case StoreException.LOCK:
e = new org.apache.openjpa.persistence.OptimisticLockException
(ke.getMessage(), getNestedThrowables(ke),
getFailedObject(ke), ke.isFatal());