Skip to content

Commit 372ea5e

Browse files
committed
proper error interpretation for InformixDialect
1 parent be1d75e commit 372ea5e

File tree

3 files changed

+73
-31
lines changed

3 files changed

+73
-31
lines changed

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixDialect.java

Lines changed: 69 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import org.hibernate.dialect.NullOrdering;
2525
import org.hibernate.dialect.Replacer;
2626
import org.hibernate.dialect.SelectItemReferenceStrategy;
27+
import org.hibernate.exception.ConstraintViolationException;
28+
import org.hibernate.exception.LockAcquisitionException;
29+
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
2730
import org.hibernate.type.descriptor.jdbc.VarcharUUIDJdbcType;
2831
import org.hibernate.dialect.function.CaseLeastGreatestEmulation;
2932
import org.hibernate.dialect.function.CommonFunctionFactory;
@@ -91,6 +94,7 @@
9194
import jakarta.persistence.TemporalType;
9295

9396
import static org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtractor.extractUsingTemplate;
97+
import static org.hibernate.internal.util.JdbcExceptionHelper.extractErrorCode;
9498
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
9599
import static org.hibernate.type.SqlTypes.BIGINT;
96100
import static org.hibernate.type.SqlTypes.BINARY;
@@ -562,46 +566,80 @@ public boolean supportsValuesListForInsert() {
562566
return false;
563567
}
564568

569+
@Override
570+
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
571+
return (sqlException, message, sql) ->
572+
switch ( extractErrorCode( sqlException ) ) {
573+
case -378, -233, -107, -113, -134, -143, -144, -154 ->
574+
//TODO: which of these are these are really LockTimeoutExceptions
575+
// rather than the more generic LockAcquisitionException?
576+
new LockAcquisitionException( message, sqlException, sql );
577+
case -239, -268 ->
578+
new ConstraintViolationException( message, sqlException, sql, ConstraintViolationException.ConstraintKind.UNIQUE,
579+
getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) );
580+
case -691, -692 ->
581+
new ConstraintViolationException( message, sqlException, sql, ConstraintViolationException.ConstraintKind.FOREIGN_KEY,
582+
getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) );
583+
case -703, -391 ->
584+
new ConstraintViolationException( message, sqlException, sql, ConstraintViolationException.ConstraintKind.NOT_NULL,
585+
getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) );
586+
case -530 ->
587+
new ConstraintViolationException( message, sqlException, sql, ConstraintViolationException.ConstraintKind.CHECK,
588+
getViolatedConstraintNameExtractor().extractConstraintName( sqlException ) );
589+
default -> null;
590+
};
591+
}
592+
565593
@Override
566594
public ViolatedConstraintNameExtractor getViolatedConstraintNameExtractor() {
567595
return EXTRACTOR;
568596
}
569597

570598
private static final ViolatedConstraintNameExtractor EXTRACTOR =
571599
new TemplatedViolatedConstraintNameExtractor( sqle -> {
572-
String constraintName;
573-
switch ( JdbcExceptionHelper.extractErrorCode( sqle ) ) {
574-
case -268:
575-
constraintName = extractUsingTemplate(
576-
"Unique constraint (",
577-
") violated.",
578-
sqle.getMessage()
579-
);
580-
break;
581-
case -691:
582-
constraintName = extractUsingTemplate(
583-
"Missing key in referenced table for referential constraint (",
584-
").",
585-
sqle.getMessage()
586-
);
587-
break;
588-
case -692:
589-
constraintName = extractUsingTemplate(
590-
"Key value for constraint (",
591-
") is still being referenced.",
592-
sqle.getMessage()
593-
);
594-
break;
595-
default:
596-
return null;
600+
final String constraintName =
601+
switch ( JdbcExceptionHelper.extractErrorCode( sqle ) ) {
602+
case -239, -268 ->
603+
extractUsingTemplate(
604+
"Unique constraint (",
605+
") violated.",
606+
sqle.getMessage()
607+
);
608+
case -691 ->
609+
extractUsingTemplate(
610+
"Missing key in referenced table for referential constraint (",
611+
").",
612+
sqle.getMessage()
613+
);
614+
case -692 ->
615+
extractUsingTemplate(
616+
"Key value for constraint (",
617+
") is still being referenced.",
618+
sqle.getMessage()
619+
);
620+
case -530 ->
621+
extractUsingTemplate(
622+
"Check constraint (",
623+
") failed",
624+
sqle.getMessage()
625+
);
626+
case -391 ->
627+
extractUsingTemplate(
628+
"null into column (",
629+
")",
630+
sqle.getMessage()
631+
);
632+
default -> null;
633+
};
634+
635+
if ( constraintName == null ) {
636+
return null;
597637
}
598-
599-
// strip table-owner because Informix always returns constraint names as "<table-owner>.<constraint-name>"
600-
final int i = constraintName.indexOf( '.' );
601-
if ( i != -1 ) {
602-
constraintName = constraintName.substring( i + 1 );
638+
else {
639+
// strip table-owner because Informix always returns constraint names as "<table-owner>.<constraint-name>"
640+
final int index = constraintName.indexOf( '.' );
641+
return index > 0 ? constraintName.substring( index + 1 ) : constraintName;
603642
}
604-
return constraintName;
605643
} );
606644

607645
@Override

hibernate-core/src/test/java/org/hibernate/orm/test/constraint/ConstraintInterpretationTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import jakarta.persistence.ManyToOne;
1414
import jakarta.persistence.Table;
1515
import jakarta.persistence.UniqueConstraint;
16+
import org.hibernate.community.dialect.InformixDialect;
1617
import org.hibernate.dialect.DB2Dialect;
1718
import org.hibernate.dialect.H2Dialect;
1819
import org.hibernate.dialect.HSQLDialect;
@@ -44,6 +45,7 @@
4445
@RequiresDialect( SybaseASEDialect.class )
4546
@RequiresDialect( OracleDialect.class )
4647
@RequiresDialect( DB2Dialect.class )
48+
@RequiresDialect( InformixDialect.class )
4749
@SkipForDialect(dialectClass = MariaDBDialect.class) // Maria doesn't allow named column-level check constraints
4850
public class ConstraintInterpretationTest {
4951
@Test void testNotNullPrimaryKey(EntityManagerFactoryScope scope) {

hibernate-core/src/test/java/org/hibernate/orm/test/constraint/ConstraintInterpretationTest2.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import jakarta.persistence.ManyToOne;
1414
import jakarta.persistence.Table;
1515
import jakarta.persistence.UniqueConstraint;
16+
import org.hibernate.community.dialect.InformixDialect;
1617
import org.hibernate.dialect.DB2Dialect;
1718
import org.hibernate.dialect.H2Dialect;
1819
import org.hibernate.dialect.HANADialect;
@@ -43,6 +44,7 @@
4344
@RequiresDialect( OracleDialect.class )
4445
@RequiresDialect( DB2Dialect.class )
4546
@RequiresDialect( HANADialect.class )
47+
@RequiresDialect( InformixDialect.class )
4648
public class ConstraintInterpretationTest2 {
4749
@Test void testNotNullPrimaryKey(EntityManagerFactoryScope scope) {
4850
scope.inTransaction( em -> {

0 commit comments

Comments
 (0)