Skip to content

Commit a0139ab

Browse files
author
Thomas Risberg
committed
added a DuplicatKeyException catagory for SQLException translation (SPR-5125)
1 parent d9f5a7a commit a0139ab

File tree

5 files changed

+108
-9
lines changed

5 files changed

+108
-9
lines changed

org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslator.java

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.springframework.dao.DeadlockLoserDataAccessException;
3333
import org.springframework.dao.PermissionDeniedDataAccessException;
3434
import org.springframework.dao.TransientDataAccessResourceException;
35+
import org.springframework.dao.DuplicateKeyException;
3536
import org.springframework.jdbc.BadSqlGrammarException;
3637
import org.springframework.jdbc.InvalidResultSetAccessException;
3738

@@ -224,6 +225,10 @@ else if (Arrays.binarySearch(this.sqlErrorCodes.getInvalidResultSetAccessCodes()
224225
logTranslation(task, sql, sqlEx, false);
225226
return new InvalidResultSetAccessException(task, sql, sqlEx);
226227
}
228+
else if (Arrays.binarySearch(this.sqlErrorCodes.getDuplicateKeyCodes(), errorCode) >= 0) {
229+
logTranslation(task, sql, sqlEx, false);
230+
return new DuplicateKeyException(buildMessage(task, sql, sqlEx), sqlEx);
231+
}
227232
else if (Arrays.binarySearch(this.sqlErrorCodes.getDataIntegrityViolationCodes(), errorCode) >= 0) {
228233
logTranslation(task, sql, sqlEx, false);
229234
return new DataIntegrityViolationException(buildMessage(task, sql, sqlEx), sqlEx);

org.springframework.jdbc/src/main/java/org/springframework/jdbc/support/SQLErrorCodes.java

+10
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public class SQLErrorCodes {
4141

4242
private String[] invalidResultSetAccessCodes = new String[0];
4343

44+
private String[] duplicateKeyCodes = new String[0];
45+
4446
private String[] dataIntegrityViolationCodes = new String[0];
4547

4648
private String[] permissionDeniedCodes = new String[0];
@@ -112,6 +114,14 @@ public String[] getInvalidResultSetAccessCodes() {
112114
return this.invalidResultSetAccessCodes;
113115
}
114116

117+
public String[] getDuplicateKeyCodes() {
118+
return duplicateKeyCodes;
119+
}
120+
121+
public void setDuplicateKeyCodes(String[] duplicateKeyCodes) {
122+
this.duplicateKeyCodes = duplicateKeyCodes;
123+
}
124+
115125
public void setDataIntegrityViolationCodes(String[] dataIntegrityViolationCodes) {
116126
this.dataIntegrityViolationCodes = StringUtils.sortStringArray(dataIntegrityViolationCodes);
117127
}

org.springframework.jdbc/src/main/resources/org/springframework/jdbc/support/sql-error-codes.xml

+39-9
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121
<property name="badSqlGrammarCodes">
2222
<value>-007,-029,-097,-104,-109,-115,-128,-199,-204,-206,-301,-408,-441,-491</value>
2323
</property>
24+
<property name="duplicateKeyCodes">
25+
<value>-803</value>
26+
</property>
2427
<property name="dataIntegrityViolationCodes">
25-
<value>-407,-530,-531,-532,-543,-544,-545,-603,-667,-803</value>
28+
<value>-407,-530,-531,-532,-543,-544,-545,-603,-667</value>
2629
</property>
2730
<property name="dataAccessResourceFailureCodes">
2831
<value>-904,-971</value>
@@ -45,8 +48,11 @@
4548
<property name="badSqlGrammarCodes">
4649
<value>42802,42821,42X01,42X02,42X03,42X04,42X05,42X06,42X07,42X08</value>
4750
</property>
51+
<property name="duplicateKeyCodes">
52+
<value>23505</value>
53+
</property>
4854
<property name="dataIntegrityViolationCodes">
49-
<value>22001,22005,23502,23503,23505,23513,X0Y32</value>
55+
<value>22001,22005,23502,23503,23513,X0Y32</value>
5056
</property>
5157
<property name="dataAccessResourceFailureCodes">
5258
<value>04501,08004,42Y07</value>
@@ -63,8 +69,11 @@
6369
<property name="badSqlGrammarCodes">
6470
<value>42000,42001,42101,42102,42111,42112,42121,42122,42132</value>
6571
</property>
72+
<property name="duplicateKeyCodes">
73+
<value>23001</value>
74+
</property>
6675
<property name="dataIntegrityViolationCodes">
67-
<value>22003,22012,22025,23000,23001</value>
76+
<value>22003,22012,22025,23000</value>
6877
</property>
6978
<property name="dataAccessResourceFailureCodes">
7079
<value>90046,90100,90117,90121,90126</value>
@@ -78,6 +87,9 @@
7887
<property name="badSqlGrammarCodes">
7988
<value>-22,-28</value>
8089
</property>
90+
<property name="duplicateKeyCodes">
91+
<value>-104</value>
92+
</property>
8193
<property name="dataIntegrityViolationCodes">
8294
<value>-9</value>
8395
</property>
@@ -93,8 +105,11 @@
93105
<property name="badSqlGrammarCodes">
94106
<value>-201,-217,-696</value>
95107
</property>
108+
<property name="duplicateKeyCodes">
109+
<value>-239,-268,-6017</value>
110+
</property>
96111
<property name="dataIntegrityViolationCodes">
97-
<value>-239,-268,-692,-11030</value>
112+
<value>-692,-11030</value>
98113
</property>
99114
</bean>
100115

@@ -108,8 +123,11 @@
108123
<property name="permissionDeniedCodes">
109124
<value>229</value>
110125
</property>
126+
<property name="duplicateKeyCodes">
127+
<value>2601,2627</value>
128+
</property>
111129
<property name="dataIntegrityViolationCodes">
112-
<value>544,2601,2627,8114,8115</value>
130+
<value>544,8114,8115</value>
113131
</property>
114132
<property name="cannotAcquireLockCodes">
115133
<value>1222</value>
@@ -123,8 +141,11 @@
123141
<property name="badSqlGrammarCodes">
124142
<value>1054,1064,1146</value>
125143
</property>
144+
<property name="duplicateKeyCodes">
145+
<value>1062</value>
146+
</property>
126147
<property name="dataIntegrityViolationCodes">
127-
<value>630,839,840,893,1062,1169,1215,1216,1217,1451,1452,1557</value>
148+
<value>630,839,840,893,1169,1215,1216,1217,1451,1452,1557</value>
128149
</property>
129150
<property name="dataAccessResourceFailureCodes">
130151
<value>1</value>
@@ -144,8 +165,11 @@
144165
<property name="invalidResultSetAccessCodes">
145166
<value>17003</value>
146167
</property>
168+
<property name="duplicateKeyCodes">
169+
<value>1</value>
170+
</property>
147171
<property name="dataIntegrityViolationCodes">
148-
<value>1,1400,1722,2291,2292</value>
172+
<value>1400,1722,2291,2292</value>
149173
</property>
150174
<property name="dataAccessResourceFailureCodes">
151175
<value>17002,17447</value>
@@ -168,8 +192,11 @@
168192
<property name="badSqlGrammarCodes">
169193
<value>03000,42000,42601,42602,42622,42804,42P01</value>
170194
</property>
195+
<property name="duplicateKeyCodes">
196+
<value>23505</value>
197+
</property>
171198
<property name="dataIntegrityViolationCodes">
172-
<value>23000,23502,23503,23505,23514</value>
199+
<value>23000,23502,23503,23514</value>
173200
</property>
174201
<property name="dataAccessResourceFailureCodes">
175202
<value>53000,53100,53200,53300</value>
@@ -196,8 +223,11 @@
196223
<property name="badSqlGrammarCodes">
197224
<value>101,102,103,104,105,106,107,108,109,110,111,112,113,116,120,121,123,207,208,213,257,512</value>
198225
</property>
226+
<property name="duplicateKeyCodes">
227+
<value>2601</value>
228+
</property>
199229
<property name="dataIntegrityViolationCodes">
200-
<value>233,423,511,515,530,547,2601,2615,2714</value>
230+
<value>233,423,511,515,530,547,2615,2714</value>
201231
</property>
202232
<property name="transientDataAccessResourceCodes">
203233
<value>921,1105</value>

org.springframework.jdbc/src/test/java/org/springframework/jdbc/support/SQLErrorCodeSQLExceptionTranslatorTests.java

+8
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.dao.DataAccessResourceFailureException;
2828
import org.springframework.dao.DataIntegrityViolationException;
2929
import org.springframework.dao.DeadlockLoserDataAccessException;
30+
import org.springframework.dao.DuplicateKeyException;
3031
import org.springframework.jdbc.BadSqlGrammarException;
3132
import org.springframework.jdbc.InvalidResultSetAccessException;
3233

@@ -39,6 +40,7 @@ public class SQLErrorCodeSQLExceptionTranslatorTests extends TestCase {
3940
static {
4041
ERROR_CODES.setBadSqlGrammarCodes(new String[] { "1", "2" });
4142
ERROR_CODES.setInvalidResultSetAccessCodes(new String[] { "3", "4" });
43+
ERROR_CODES.setDuplicateKeyCodes(new String[] {"10"});
4244
ERROR_CODES.setDataAccessResourceFailureCodes(new String[] { "5" });
4345
ERROR_CODES.setDataIntegrityViolationCodes(new String[] { "6" });
4446
ERROR_CODES.setCannotAcquireLockCodes(new String[] { "7" });
@@ -64,6 +66,12 @@ public void testErrorCodeTranslation() {
6466
checkTranslation(sext, 7, CannotAcquireLockException.class);
6567
checkTranslation(sext, 8, DeadlockLoserDataAccessException.class);
6668
checkTranslation(sext, 9, CannotSerializeTransactionException.class);
69+
checkTranslation(sext, 10, DuplicateKeyException.class);
70+
71+
SQLException dupKeyEx = new SQLException("", "", 10);
72+
DataAccessException dksex = sext.translate("task", "SQL", dupKeyEx);
73+
assertTrue("Not instance of DataIntegrityViolationException",
74+
DataIntegrityViolationException.class.isAssignableFrom(dksex.getClass()));
6775

6876
// Test fallback. We assume that no database will ever return this error code,
6977
// but 07xxx will be bad grammar picked up by the fallback SQLState translator
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2002-2009 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.dao;
18+
19+
/**
20+
* Exception thrown when an attempt to insert or update data
21+
* results in violation of an primary key or unique constraint.
22+
* Note that this is not necessarily a purely relational concept;
23+
* unique primary keys are required by most database types.
24+
*
25+
* @author Thomas Risberg
26+
*/
27+
public class DuplicateKeyException extends DataIntegrityViolationException {
28+
29+
/**
30+
* Constructor for DuplicateKeyException.
31+
* @param msg the detail message
32+
*/
33+
public DuplicateKeyException(String msg) {
34+
super(msg);
35+
}
36+
37+
/**
38+
* Constructor for DuplicateKeyException.
39+
* @param msg the detail message
40+
* @param cause the root cause from the data access API in use
41+
*/
42+
public DuplicateKeyException(String msg, Throwable cause) {
43+
super(msg, cause);
44+
}
45+
46+
}

0 commit comments

Comments
 (0)