Skip to content

Commit 11ae0f7

Browse files
committed
HHH-9166 handle nested exceptions with TemplatedViolatedConstraintNameExtracter
1 parent 1e54ee3 commit 11ae0f7

File tree

11 files changed

+116
-87
lines changed

11 files changed

+116
-87
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/Cache71Dialect.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import java.sql.CallableStatement;
10-
import java.sql.ResultSet;
11-
import java.sql.SQLException;
12-
import java.sql.Types;
13-
149
import org.hibernate.LockMode;
1510
import org.hibernate.MappingException;
1611
import org.hibernate.cfg.Environment;
@@ -47,6 +42,11 @@
4742
import org.hibernate.sql.JoinFragment;
4843
import org.hibernate.type.StandardBasicTypes;
4944

45+
import java.sql.CallableStatement;
46+
import java.sql.ResultSet;
47+
import java.sql.SQLException;
48+
import java.sql.Types;
49+
5050
/**
5151
* Caché 2007.1 dialect.
5252
*
@@ -669,7 +669,7 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
669669
*/
670670
public static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
671671
@Override
672-
public String extractConstraintName(SQLException sqle) {
672+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
673673
return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
674674
}
675675
};

hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import java.sql.SQLException;
10-
import java.sql.Types;
11-
129
import org.hibernate.JDBCException;
1310
import org.hibernate.PessimisticLockException;
1411
import org.hibernate.boot.TempTableDdlTransactionHandling;
@@ -37,9 +34,11 @@
3734
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
3835
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
3936
import org.hibernate.type.StandardBasicTypes;
40-
4137
import org.jboss.logging.Logger;
4238

39+
import java.sql.SQLException;
40+
import java.sql.Types;
41+
4342
/**
4443
* A dialect compatible with the H2 database.
4544
*
@@ -335,7 +334,8 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
335334
* @param sqle The exception that was the result of the constraint violation.
336335
* @return The extracted constraint name.
337336
*/
338-
public String extractConstraintName(SQLException sqle) {
337+
@Override
338+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
339339
String constraintName = null;
340340
// 23000: Check constraint violation: {0}
341341
// 23001: Unique index or primary key violation: {0}

hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import java.io.Serializable;
10-
import java.sql.SQLException;
11-
import java.sql.Types;
12-
import java.util.Locale;
13-
149
import org.hibernate.JDBCException;
1510
import org.hibernate.LockMode;
1611
import org.hibernate.MappingException;
@@ -46,9 +41,13 @@
4641
import org.hibernate.internal.util.ReflectHelper;
4742
import org.hibernate.persister.entity.Lockable;
4843
import org.hibernate.type.StandardBasicTypes;
49-
5044
import org.jboss.logging.Logger;
5145

46+
import java.io.Serializable;
47+
import java.sql.SQLException;
48+
import java.sql.Types;
49+
import java.util.Locale;
50+
5251
/**
5352
* An SQL dialect compatible with HSQLDB (HyperSQL).
5453
* <p/>
@@ -393,7 +392,7 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
393392

394393
private static final ViolatedConstraintNameExtracter EXTRACTER_18 = new TemplatedViolatedConstraintNameExtracter() {
395394
@Override
396-
public String extractConstraintName(SQLException sqle) {
395+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
397396
String constraintName = null;
398397

399398
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
@@ -430,7 +429,7 @@ else if ( errorCode == -177 ) {
430429
*/
431430
private static final ViolatedConstraintNameExtracter EXTRACTER_20 = new TemplatedViolatedConstraintNameExtracter() {
432431
@Override
433-
public String extractConstraintName(SQLException sqle) {
432+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
434433
String constraintName = null;
435434

436435
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );

hibernate-core/src/main/java/org/hibernate/dialect/InformixDialect.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import java.sql.SQLException;
10-
import java.sql.Types;
11-
import java.util.Locale;
12-
139
import org.hibernate.MappingException;
1410
import org.hibernate.dialect.function.VarArgsSQLFunction;
1511
import org.hibernate.dialect.pagination.FirstLimitHandler;
@@ -26,6 +22,10 @@
2622
import org.hibernate.internal.util.StringHelper;
2723
import org.hibernate.type.StandardBasicTypes;
2824

25+
import java.sql.SQLException;
26+
import java.sql.Types;
27+
import java.util.Locale;
28+
2929
/**
3030
* Informix dialect.<br>
3131
* <br>
@@ -223,7 +223,7 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
223223

224224
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
225225
@Override
226-
public String extractConstraintName(SQLException sqle) {
226+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
227227
String constraintName = null;
228228
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
229229

hibernate-core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import java.sql.SQLException;
10-
import java.sql.Types;
11-
129
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
1310
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
1411
import org.hibernate.internal.util.JdbcExceptionHelper;
1512

13+
import java.sql.SQLException;
14+
import java.sql.Types;
15+
1616
/**
1717
* An SQL dialect for MySQL 5.x specific features.
1818
*
@@ -38,17 +38,13 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
3838

3939
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
4040

41-
public String extractConstraintName(SQLException sqle) {
42-
try {
43-
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) ).intValue();
44-
switch ( sqlState ) {
45-
case 23000:
46-
return extractUsingTemplate( " for key '", "'", sqle.getMessage() );
47-
default:
48-
return null;
49-
}
50-
}
51-
catch ( NumberFormatException nfe ) {
41+
@Override
42+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
43+
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) ).intValue();
44+
switch ( sqlState ) {
45+
case 23000:
46+
return extractUsingTemplate( " for key '", "'", sqle.getMessage() );
47+
default:
5248
return null;
5349
}
5450
}

hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import java.sql.CallableStatement;
10-
import java.sql.ResultSet;
11-
import java.sql.SQLException;
12-
import java.sql.Types;
13-
import java.util.List;
14-
import java.util.Locale;
15-
169
import org.hibernate.JDBCException;
1710
import org.hibernate.QueryTimeoutException;
1811
import org.hibernate.annotations.common.util.StringHelper;
@@ -47,6 +40,13 @@
4740
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
4841
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
4942

43+
import java.sql.CallableStatement;
44+
import java.sql.ResultSet;
45+
import java.sql.SQLException;
46+
import java.sql.Types;
47+
import java.util.List;
48+
import java.util.Locale;
49+
5050
/**
5151
* A dialect for Oracle 8i.
5252
*
@@ -469,7 +469,8 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
469469
* @param sqle The exception that was the result of the constraint violation.
470470
* @return The extracted constraint name.
471471
*/
472-
public String extractConstraintName(SQLException sqle) {
472+
@Override
473+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
473474
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
474475
if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
475476
return extractUsingTemplate( "(", ")", sqle.getMessage() );

hibernate-core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import java.sql.CallableStatement;
10-
import java.sql.ResultSet;
11-
import java.sql.SQLException;
12-
import java.sql.Types;
13-
import java.util.Locale;
14-
159
import org.hibernate.cfg.Environment;
1610
import org.hibernate.dialect.function.NoArgSQLFunction;
1711
import org.hibernate.dialect.function.NvlFunction;
@@ -21,15 +15,20 @@
2115
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
2216
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
2317
import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
24-
import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
2518
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
19+
import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
2620
import org.hibernate.hql.spi.id.local.AfterUseAction;
2721
import org.hibernate.internal.CoreMessageLogger;
2822
import org.hibernate.internal.util.JdbcExceptionHelper;
2923
import org.hibernate.type.StandardBasicTypes;
30-
3124
import org.jboss.logging.Logger;
3225

26+
import java.sql.CallableStatement;
27+
import java.sql.ResultSet;
28+
import java.sql.SQLException;
29+
import java.sql.Types;
30+
import java.util.Locale;
31+
3332
/**
3433
* An SQL dialect for Oracle 9 (uses ANSI-style syntax where possible).
3534
*
@@ -299,7 +298,7 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
299298

300299
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
301300
@Override
302-
public String extractConstraintName(SQLException sqle) {
301+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
303302
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
304303
if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
305304
return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );

hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQL81Dialect.java

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@
66
*/
77
package org.hibernate.dialect;
88

9-
import java.sql.CallableStatement;
10-
import java.sql.ResultSet;
11-
import java.sql.SQLException;
12-
import java.sql.Types;
13-
149
import org.hibernate.JDBCException;
1510
import org.hibernate.LockOptions;
1611
import org.hibernate.PessimisticLockException;
@@ -41,6 +36,11 @@
4136
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
4237
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
4338

39+
import java.sql.CallableStatement;
40+
import java.sql.ResultSet;
41+
import java.sql.SQLException;
42+
import java.sql.Types;
43+
4444
/**
4545
* An SQL dialect for Postgres
4646
* <p/>
@@ -406,26 +406,22 @@ public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
406406
* Orginally contributed by Denny Bartelt.
407407
*/
408408
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
409-
public String extractConstraintName(SQLException sqle) {
410-
try {
411-
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) );
412-
switch (sqlState) {
413-
// CHECK VIOLATION
414-
case 23514: return extractUsingTemplate( "violates check constraint \"","\"", sqle.getMessage() );
415-
// UNIQUE VIOLATION
416-
case 23505: return extractUsingTemplate( "violates unique constraint \"","\"", sqle.getMessage() );
417-
// FOREIGN KEY VIOLATION
418-
case 23503: return extractUsingTemplate( "violates foreign key constraint \"","\"", sqle.getMessage() );
419-
// NOT NULL VIOLATION
420-
case 23502: return extractUsingTemplate( "null value in column \"","\" violates not-null constraint", sqle.getMessage() );
421-
// TODO: RESTRICT VIOLATION
422-
case 23001: return null;
423-
// ALL OTHER
424-
default: return null;
425-
}
426-
}
427-
catch (NumberFormatException nfe) {
428-
return null;
409+
@Override
410+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
411+
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) );
412+
switch (sqlState) {
413+
// CHECK VIOLATION
414+
case 23514: return extractUsingTemplate( "violates check constraint \"","\"", sqle.getMessage() );
415+
// UNIQUE VIOLATION
416+
case 23505: return extractUsingTemplate( "violates unique constraint \"","\"", sqle.getMessage() );
417+
// FOREIGN KEY VIOLATION
418+
case 23503: return extractUsingTemplate( "violates foreign key constraint \"","\"", sqle.getMessage() );
419+
// NOT NULL VIOLATION
420+
case 23502: return extractUsingTemplate( "null value in column \"","\" violates not-null constraint", sqle.getMessage() );
421+
// TODO: RESTRICT VIOLATION
422+
case 23001: return null;
423+
// ALL OTHER
424+
default: return null;
429425
}
430426
}
431427
};

hibernate-core/src/main/java/org/hibernate/dialect/Teradata14Dialect.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public ResultSet getResultSet(CallableStatement cs) throws SQLException {
144144
* @return The extracted constraint name.
145145
*/
146146
@Override
147-
public String extractConstraintName(SQLException sqle) {
147+
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
148148
String constraintName = null;
149149

150150
int errorCode = sqle.getErrorCode();

hibernate-core/src/main/java/org/hibernate/exception/spi/TemplatedViolatedConstraintNameExtracter.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,41 @@
66
*/
77
package org.hibernate.exception.spi;
88

9+
import java.sql.SQLException;
10+
911
/**
1012
* Knows how to extract a violated constraint name from an error message based on the
1113
* fact that the constraint name is templated within the message.
1214
*
1315
* @author Steve Ebersole
16+
* @author Brett Meyer
1417
*/
1518
public abstract class TemplatedViolatedConstraintNameExtracter implements ViolatedConstraintNameExtracter {
1619

20+
@Override
21+
public String extractConstraintName(SQLException sqle) {
22+
try {
23+
String constraintName = null;
24+
25+
// handle nested exceptions
26+
do {
27+
constraintName = doExtractConstraintName(sqle);
28+
if (sqle.getNextException() == null
29+
|| sqle.getNextException() == sqle) {
30+
break;
31+
} else {
32+
sqle = sqle.getNextException();
33+
}
34+
} while (constraintName == null);
35+
36+
return constraintName;
37+
} catch (NumberFormatException nfe) {
38+
return null;
39+
}
40+
}
41+
42+
protected abstract String doExtractConstraintName(SQLException sqle) throws NumberFormatException;
43+
1744
/**
1845
* Extracts the constraint name based on a template (i.e., <i>templateStart</i><b>constraintName</b><i>templateEnd</i>).
1946
*

0 commit comments

Comments
 (0)