HHH-9166 handle nested exceptions with TemplatedViolatedConstraintNameExtracter
This commit is contained in:
parent
1e54ee3dc1
commit
11ae0f72c8
|
@ -6,11 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
@ -47,6 +42,11 @@ import org.hibernate.sql.CacheJoinFragment;
|
|||
import org.hibernate.sql.JoinFragment;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
* Caché 2007.1 dialect.
|
||||
*
|
||||
|
@ -669,7 +669,7 @@ public class Cache71Dialect extends Dialect {
|
|||
*/
|
||||
public static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
|
||||
}
|
||||
};
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.PessimisticLockException;
|
||||
import org.hibernate.boot.TempTableDdlTransactionHandling;
|
||||
|
@ -37,9 +34,11 @@ import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorH2
|
|||
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
* A dialect compatible with the H2 database.
|
||||
*
|
||||
|
@ -335,7 +334,8 @@ public class H2Dialect extends Dialect {
|
|||
* @param sqle The exception that was the result of the constraint violation.
|
||||
* @return The extracted constraint name.
|
||||
*/
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
@Override
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
String constraintName = null;
|
||||
// 23000: Check constraint violation: {0}
|
||||
// 23001: Unique index or primary key violation: {0}
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MappingException;
|
||||
|
@ -46,9 +41,13 @@ import org.hibernate.internal.util.JdbcExceptionHelper;
|
|||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.persister.entity.Lockable;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* An SQL dialect compatible with HSQLDB (HyperSQL).
|
||||
* <p/>
|
||||
|
@ -393,7 +392,7 @@ public class HSQLDialect extends Dialect {
|
|||
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER_18 = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
String constraintName = null;
|
||||
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
|
@ -430,7 +429,7 @@ public class HSQLDialect extends Dialect {
|
|||
*/
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER_20 = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
String constraintName = null;
|
||||
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
|
|
|
@ -6,10 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.dialect.function.VarArgsSQLFunction;
|
||||
import org.hibernate.dialect.pagination.FirstLimitHandler;
|
||||
|
@ -26,6 +22,10 @@ import org.hibernate.internal.util.JdbcExceptionHelper;
|
|||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Informix dialect.<br>
|
||||
* <br>
|
||||
|
@ -223,7 +223,7 @@ public class InformixDialect extends Dialect {
|
|||
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
String constraintName = null;
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
* An SQL dialect for MySQL 5.x specific features.
|
||||
*
|
||||
|
@ -38,17 +38,13 @@ public class MySQL5Dialect extends MySQLDialect {
|
|||
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
try {
|
||||
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) ).intValue();
|
||||
switch ( sqlState ) {
|
||||
case 23000:
|
||||
return extractUsingTemplate( " for key '", "'", sqle.getMessage() );
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch ( NumberFormatException nfe ) {
|
||||
@Override
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) ).intValue();
|
||||
switch ( sqlState ) {
|
||||
case 23000:
|
||||
return extractUsingTemplate( " for key '", "'", sqle.getMessage() );
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,13 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.QueryTimeoutException;
|
||||
import org.hibernate.annotations.common.util.StringHelper;
|
||||
|
@ -47,6 +40,13 @@ import org.hibernate.type.StandardBasicTypes;
|
|||
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A dialect for Oracle 8i.
|
||||
*
|
||||
|
@ -469,7 +469,8 @@ public class Oracle8iDialect extends Dialect {
|
|||
* @param sqle The exception that was the result of the constraint violation.
|
||||
* @return The extracted constraint name.
|
||||
*/
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
@Override
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
|
||||
return extractUsingTemplate( "(", ")", sqle.getMessage() );
|
||||
|
|
|
@ -6,12 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
import org.hibernate.dialect.function.NvlFunction;
|
||||
|
@ -21,15 +15,20 @@ import org.hibernate.dialect.function.VarArgsSQLFunction;
|
|||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
|
||||
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
|
||||
import org.hibernate.hql.spi.id.IdTableSupportStandardImpl;
|
||||
import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
|
||||
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
|
||||
import org.hibernate.hql.spi.id.global.GlobalTemporaryTableBulkIdStrategy;
|
||||
import org.hibernate.hql.spi.id.local.AfterUseAction;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* An SQL dialect for Oracle 9 (uses ANSI-style syntax where possible).
|
||||
*
|
||||
|
@ -299,7 +298,7 @@ public class Oracle9Dialect extends Dialect {
|
|||
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle );
|
||||
if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
|
||||
return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.PessimisticLockException;
|
||||
|
@ -41,6 +36,11 @@ import org.hibernate.type.descriptor.sql.BlobTypeDescriptor;
|
|||
import org.hibernate.type.descriptor.sql.ClobTypeDescriptor;
|
||||
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
/**
|
||||
* An SQL dialect for Postgres
|
||||
* <p/>
|
||||
|
@ -406,26 +406,22 @@ public class PostgreSQL81Dialect extends Dialect {
|
|||
* Orginally contributed by Denny Bartelt.
|
||||
*/
|
||||
private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
try {
|
||||
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) );
|
||||
switch (sqlState) {
|
||||
// CHECK VIOLATION
|
||||
case 23514: return extractUsingTemplate( "violates check constraint \"","\"", sqle.getMessage() );
|
||||
// UNIQUE VIOLATION
|
||||
case 23505: return extractUsingTemplate( "violates unique constraint \"","\"", sqle.getMessage() );
|
||||
// FOREIGN KEY VIOLATION
|
||||
case 23503: return extractUsingTemplate( "violates foreign key constraint \"","\"", sqle.getMessage() );
|
||||
// NOT NULL VIOLATION
|
||||
case 23502: return extractUsingTemplate( "null value in column \"","\" violates not-null constraint", sqle.getMessage() );
|
||||
// TODO: RESTRICT VIOLATION
|
||||
case 23001: return null;
|
||||
// ALL OTHER
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException nfe) {
|
||||
return null;
|
||||
@Override
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) );
|
||||
switch (sqlState) {
|
||||
// CHECK VIOLATION
|
||||
case 23514: return extractUsingTemplate( "violates check constraint \"","\"", sqle.getMessage() );
|
||||
// UNIQUE VIOLATION
|
||||
case 23505: return extractUsingTemplate( "violates unique constraint \"","\"", sqle.getMessage() );
|
||||
// FOREIGN KEY VIOLATION
|
||||
case 23503: return extractUsingTemplate( "violates foreign key constraint \"","\"", sqle.getMessage() );
|
||||
// NOT NULL VIOLATION
|
||||
case 23502: return extractUsingTemplate( "null value in column \"","\" violates not-null constraint", sqle.getMessage() );
|
||||
// TODO: RESTRICT VIOLATION
|
||||
case 23001: return null;
|
||||
// ALL OTHER
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -144,7 +144,7 @@ public class Teradata14Dialect extends TeradataDialect {
|
|||
* @return The extracted constraint name.
|
||||
*/
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
protected String doExtractConstraintName(SQLException sqle) throws NumberFormatException {
|
||||
String constraintName = null;
|
||||
|
||||
int errorCode = sqle.getErrorCode();
|
||||
|
|
|
@ -6,14 +6,41 @@
|
|||
*/
|
||||
package org.hibernate.exception.spi;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Knows how to extract a violated constraint name from an error message based on the
|
||||
* fact that the constraint name is templated within the message.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Brett Meyer
|
||||
*/
|
||||
public abstract class TemplatedViolatedConstraintNameExtracter implements ViolatedConstraintNameExtracter {
|
||||
|
||||
@Override
|
||||
public String extractConstraintName(SQLException sqle) {
|
||||
try {
|
||||
String constraintName = null;
|
||||
|
||||
// handle nested exceptions
|
||||
do {
|
||||
constraintName = doExtractConstraintName(sqle);
|
||||
if (sqle.getNextException() == null
|
||||
|| sqle.getNextException() == sqle) {
|
||||
break;
|
||||
} else {
|
||||
sqle = sqle.getNextException();
|
||||
}
|
||||
} while (constraintName == null);
|
||||
|
||||
return constraintName;
|
||||
} catch (NumberFormatException nfe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract String doExtractConstraintName(SQLException sqle) throws NumberFormatException;
|
||||
|
||||
/**
|
||||
* Extracts the constraint name based on a template (i.e., <i>templateStart</i><b>constraintName</b><i>templateEnd</i>).
|
||||
*
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
|
@ -21,13 +16,19 @@ import org.hibernate.testing.TestForIssue;
|
|||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.BatchUpdateException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Testing of patched support for PostgreSQL Lock error detection. HHH-7251
|
||||
*
|
||||
* @author Bryan Varner
|
||||
*/
|
||||
@TestForIssue( jiraKey = "HHH-7251" )
|
||||
public class PostgreSQL81DialectTestCase extends BaseUnitTestCase {
|
||||
|
||||
@Test
|
||||
|
@ -67,4 +68,14 @@ public class PostgreSQL81DialectTestCase extends BaseUnitTestCase {
|
|||
forUpdateClause = dialect.getForUpdateString("tableAlias1,tableAlias2", lockOptions);
|
||||
assertTrue("for update of tableAlias1,tableAlias2".equals(forUpdateClause));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractConstraintName() {
|
||||
PostgreSQL81Dialect dialect = new PostgreSQL81Dialect();
|
||||
SQLException psqlException = new java.sql.SQLException("ERROR: duplicate key value violates unique constraint \"uk_4bm1x2ultdmq63y3h5r3eg0ej\" Detail: Key (username, server_config)=(user, 1) already exists.", "23505");
|
||||
BatchUpdateException batchUpdateException = new BatchUpdateException("Concurrent Error", "23505", null);
|
||||
batchUpdateException.setNextException(psqlException);
|
||||
String constraintName = dialect.getViolatedConstraintNameExtracter().extractConstraintName(batchUpdateException);
|
||||
assertThat(constraintName, is("uk_4bm1x2ultdmq63y3h5r3eg0ej"));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue