diff --git a/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs b/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs
index 44363ac8..29e30c40 100644
--- a/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs
+++ b/src/Spring/Spring.Data/Data/Common/ErrorCodes.cs
@@ -39,23 +39,25 @@ namespace Spring.Data.Common
public class ErrorCodes
{
#region Fields
- private String[] databaseProductNames;
+ private string[] databaseProductNames;
- private String[] badSqlGrammarCodes = new String[0];
+ private string[] badSqlGrammarCodes = new String[0];
- private String[] invalidResultSetAccessCodes = new String[0];
+ private string[] invalidResultSetAccessCodes = new String[0];
- private String[] dataAccessResourceFailureCodes = new String[0];
+ private string[] dataAccessResourceFailureCodes = new String[0];
- private String[] permissionDeniedCodes = new String[0];
+ private string[] permissionDeniedCodes = new String[0];
- private String[] dataIntegrityViolationCodes = new String[0];
+ private string[] dataIntegrityViolationCodes = new String[0];
- private String[] cannotAcquireLockCodes = new String[0];
+ private string[] cannotAcquireLockCodes = new String[0];
- private String[] deadlockLoserCodes = new String[0];
+ private string[] deadlockLoserCodes = new String[0];
- private String[] cannotSerializeTransactionCodes = new String[0];
+ private string[] cannotSerializeTransactionCodes = new String[0];
+
+ private string[] duplicateKeyCodes = new string[0];
// CustomErrorCodesTranslation[] customTranslations;
#endregion
@@ -144,13 +146,14 @@ namespace Spring.Data.Common
get { return cannotSerializeTransactionCodes; }
set { cannotSerializeTransactionCodes = value; }
}
-
- #endregion
- #region Methods
+ public string[] DuplicateKeyCodes
+ {
+ get { return duplicateKeyCodes; }
+ set { duplicateKeyCodes = value; }
+ }
#endregion
-
}
}
\ No newline at end of file
diff --git a/src/Spring/Spring.Data/Data/DuplicateKeyException.cs b/src/Spring/Spring.Data/Data/DuplicateKeyException.cs
new file mode 100644
index 00000000..1b4f92c3
--- /dev/null
+++ b/src/Spring/Spring.Data/Data/DuplicateKeyException.cs
@@ -0,0 +1,141 @@
+#region License
+
+/*
+ * Copyright © 2002-2005 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#endregion
+
+#region Imports
+
+using System;
+using System.Runtime.Serialization;
+using Spring.Dao;
+
+#endregion
+
+namespace Spring.Data
+{
+ ///
+ /// Exception thrown when an attempt to insert or update data
+ /// results in violation of an primary key or unique constraint.
+ /// Note that this is not necessarily a purely relational concept;
+ /// unique primary keys are required by most database types.
+ ///
+ /// Thomas Risberg
+ /// Mark Pollack (.NET)
+ [Serializable]
+ public class DuplicateKeyException : DataIntegrityViolationException
+ {
+ #region Fields
+
+ ///
+ /// SQL that led to the problem
+ ///
+ private string sql;
+
+ #endregion
+
+ #region Constructor (s)
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DuplicateKeyException()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A message about the exception.
+ public DuplicateKeyException(string message): base(message)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A message about the exception.
+ /// The inner exception.
+ public DuplicateKeyException(string message, Exception inner): base(message, inner)
+ {
+ }
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// name of the current task.
+ /// The offending SQL statment
+ /// The root cause.
+ public DuplicateKeyException(string task, String sql, Exception ex) : base(task + "; Duplicate key for SQL [" + sql + "]; " + ex.Message, ex)
+ {
+ this.sql = sql;
+ }
+ ///
+ /// Creates a new instance of the
+ /// class.
+ ///
+ ///
+ /// The
+ /// that holds the serialized object data about the exception being thrown.
+ ///
+ ///
+ /// The
+ /// that contains contextual information about the source or destination.
+ ///
+ protected DuplicateKeyException(SerializationInfo info, StreamingContext context) : base(info, context) { }
+
+
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Gets the SQL that caused the exception
+ ///
+ /// The SQL that caused the exception.
+ public string Sql
+ {
+ get
+ {
+ return sql;
+ }
+ }
+ #endregion
+
+ #region Methods
+
+ #endregion
+
+ #region ISerializable Members
+
+ ///
+ /// When overridden in a derived class, sets the
+ /// with information about the exception.
+ ///
+ /// The that holds the serialized object data about the exception being thrown.
+ /// The that contains contextual information about the source or destination.
+ /// The parameter is a null reference ( in Visual Basic).
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ info.AddValue( "sql", sql );
+ base.GetObjectData( info, context );
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs b/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs
index 01d3b4f4..f417a87c 100644
--- a/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs
+++ b/src/Spring/Spring.Data/Data/Support/ErrorCodeExceptionTranslator.cs
@@ -141,7 +141,8 @@ namespace Spring.Data.Support
#endregion
- ///
+
+ ///
/// Translate the given into a generic data access exception.
///
/// A readable string describing the task being attempted.
@@ -152,19 +153,61 @@ namespace Spring.Data.Support
///
/// A appropriate for the supplied
/// .
- ///
- public virtual DataAccessException Translate(string task, string sql, Exception exception)
+ ///
+ public virtual DataAccessException Translate(string task, string sql, Exception exception)
+ {
+ if (task == null)
+ {
+ task = "";
+ }
+ if (sql == null)
+ {
+ sql = "";
+ }
+ string errorCode = ExtractErrorCode(exception);
+
+ // First, try custom translation from overridden method.
+ DataAccessException dex = DoTranslate(task, sql, errorCode, exception);
+ if (dex != null)
+ {
+ // Specific exception match found.
+ return dex;
+ }
+ // Looking for a fallback...
+ if (log.IsDebugEnabled)
+ {
+ log.Debug("Unable to translate exception eith errorCode '" + errorCode + "', will use the fallback translator");
+ }
+ IAdoExceptionTranslator fallback = FallbackTranslator;
+ if (fallback != null)
+ {
+ return FallbackTranslator.Translate(task, sql, exception);
+ }
+ // We couldn't identify it more precisely.
+ return new UncategorizedAdoException(task, sql, errorCode, exception);
+
+
+ }
+
+ ///
+ /// Template method for actually translating the given exception.
+ /// given into a generic data access exception.
+ ///
+ /// A readable string describing the task being attempted.
+ /// The SQL query or update that caused the problem. May be null.
+ /// The error code.
+ /// The encountered by the ADO.NET implementation.
+ ///
+ /// A appropriate for the supplied
+ /// .
+ ///
+ ///
+ /// The passed-in arguments will have been pre-checked. furthermore, this method is allowed to
+ /// return null to indicate that no exception match has been found and that
+ /// fallback translation should kick in.
+ ///
+ protected virtual DataAccessException DoTranslate(string task, string sql, string errorCode, Exception exception)
{
- if (task == null)
- {
- task = "";
- }
- if (sql == null)
- {
- sql = "";
- }
- string errorCode = ExtractErrorCode(exception);
-
// First, try custom translation from overridden method.
DataAccessException dex = TranslateException(task, sql, errorCode, exception);
if (dex != null)
@@ -187,6 +230,11 @@ namespace Spring.Data.Support
{
LogTranslation(task, sql, errorCode, exception, false);
return new InvalidResultSetAccessException(task, sql, exception);
+ }
+ else if (Array.IndexOf(errorCodes.DuplicateKeyCodes, errorCode) >= 0)
+ {
+ LogTranslation(task, sql, errorCode, exception, false);
+ return new DuplicateKeyException(task, sql, exception);
}
else if (Array.IndexOf(errorCodes.DataAccessResourceFailureCodes, errorCode) >= 0)
{
@@ -220,11 +268,7 @@ namespace Spring.Data.Support
}
}
}
- if (log.IsDebugEnabled)
- {
- log.Debug("Unable to translate exception eith errorCode '" + errorCode + "', will use the fallback translator");
- }
- return fallbackTranslator.Translate(task, sql, exception);
+ return null;
}
///
diff --git a/src/Spring/Spring.Data/Spring.Data.2005.csproj b/src/Spring/Spring.Data/Spring.Data.2005.csproj
index 20050270..3dc5317f 100644
--- a/src/Spring/Spring.Data/Spring.Data.2005.csproj
+++ b/src/Spring/Spring.Data/Spring.Data.2005.csproj
@@ -39,7 +39,7 @@
false
false
false
- false
+ true
4
full
prompt
@@ -147,6 +147,7 @@
+
diff --git a/src/Spring/Spring.Data/Spring.Data.2008.csproj b/src/Spring/Spring.Data/Spring.Data.2008.csproj
index 55e4b3f8..b753c6a8 100644
--- a/src/Spring/Spring.Data/Spring.Data.2008.csproj
+++ b/src/Spring/Spring.Data/Spring.Data.2008.csproj
@@ -1,7 +1,7 @@

Local
- 9.0.21022
+ 9.0.30729
2.0
{AE00E5AB-C39A-436F-86D2-33BFE33E2E40}
Debug
@@ -155,6 +155,7 @@
+