Browse Source

Detect Informix error codes as DuplicateKeyException

Closes gh-35400

Signed-off-by: Lukáš Kvídera <kvideral@qwsome.eu>
pull/35587/head
Lukáš Kvídera 4 months ago committed by Sam Brannen
parent
commit
db9e938ec4
  1. 4
      spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java
  2. 10
      spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java
  3. 4
      spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/ConnectionFactoryUtils.java
  4. 55
      spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/ConnectionFactoryUtilsTests.java

4
spring-jdbc/src/main/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslator.java

@ -94,7 +94,9 @@ public class SQLStateSQLExceptionTranslator extends AbstractFallbackSQLException
301, // SAP HANA 301, // SAP HANA
1062, // MySQL/MariaDB 1062, // MySQL/MariaDB
2601, // MS SQL Server 2601, // MS SQL Server
2627 // MS SQL Server 2627, // MS SQL Server
-239, // Informix
-268 // Informix
); );

10
spring-jdbc/src/test/java/org/springframework/jdbc/support/SQLStateSQLExceptionTranslatorTests.java

@ -90,6 +90,16 @@ class SQLStateSQLExceptionTranslatorTests {
assertTranslation("23000", 301, DuplicateKeyException.class); assertTranslation("23000", 301, DuplicateKeyException.class);
} }
@Test
void translateDuplicateKeyInformix1() {
assertTranslation("23000", -239, DuplicateKeyException.class);
}
@Test
void translateDuplicateKeyInformix2() {
assertTranslation("23000", -268, DuplicateKeyException.class);
}
@Test @Test
void translateDataAccessResourceFailure() { void translateDataAccessResourceFailure() {
assertTranslation("53", DataAccessResourceFailureException.class); assertTranslation("53", DataAccessResourceFailureException.class);

4
spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/ConnectionFactoryUtils.java

@ -76,7 +76,9 @@ public abstract class ConnectionFactoryUtils {
301, // SAP HANA 301, // SAP HANA
1062, // MySQL/MariaDB 1062, // MySQL/MariaDB
2601, // MS SQL Server 2601, // MS SQL Server
2627 // MS SQL Server 2627, // MS SQL Server
-239, // Informix
-268 // Informix
); );

55
spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/ConnectionFactoryUtilsTests.java

@ -25,7 +25,9 @@ import io.r2dbc.spi.R2dbcRollbackException;
import io.r2dbc.spi.R2dbcTimeoutException; import io.r2dbc.spi.R2dbcTimeoutException;
import io.r2dbc.spi.R2dbcTransientResourceException; import io.r2dbc.spi.R2dbcTransientResourceException;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.dao.CannotAcquireLockException; import org.springframework.dao.CannotAcquireLockException;
import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DataIntegrityViolationException;
@ -37,8 +39,12 @@ import org.springframework.dao.TransientDataAccessResourceException;
import org.springframework.r2dbc.BadSqlGrammarException; import org.springframework.r2dbc.BadSqlGrammarException;
import org.springframework.r2dbc.UncategorizedR2dbcException; import org.springframework.r2dbc.UncategorizedR2dbcException;
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
* Tests for {@link ConnectionFactoryUtils}. * Tests for {@link ConnectionFactoryUtils}.
* *
@ -86,35 +92,32 @@ class ConnectionFactoryUtilsTests {
assertThat(exception).isExactlyInstanceOf(DataAccessResourceFailureException.class); assertThat(exception).isExactlyInstanceOf(DataAccessResourceFailureException.class);
} }
private static Stream<Arguments> duplicateKeyErrorCodes() {
return Stream.of(
Arguments.of("Oracle", "23505", 0),
Arguments.of("Oracle", "23000", 1),
Arguments.of("SAP HANA", "23000", 301),
Arguments.of("MySQL/MariaDB", "23000", 1062),
Arguments.of("MS SQL Server", "23000", 2601),
Arguments.of("MS SQL Server", "23000", 2627),
Arguments.of("Informix", "23000", -239),
Arguments.of("Informix", "23000", -268)
);
}
@ParameterizedTest
@MethodSource("duplicateKeyErrorCodes")
void shouldTranslateIntegrityViolationException(final String db, String sqlState, final int errorCode) {
Exception exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new R2dbcDataIntegrityViolationException("reason", sqlState, errorCode));
assertThat(exception).as(db).isExactlyInstanceOf(DuplicateKeyException.class);
}
@Test @Test
void shouldTranslateIntegrityViolationException() { void shouldTranslateGenericIntegrityViolationException() {
Exception exception = ConnectionFactoryUtils.convertR2dbcException("", "", Exception exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new R2dbcDataIntegrityViolationException()); new R2dbcDataIntegrityViolationException());
assertThat(exception).isExactlyInstanceOf(DataIntegrityViolationException.class); assertThat(exception).isExactlyInstanceOf(DataIntegrityViolationException.class);
exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new R2dbcDataIntegrityViolationException("reason", "23505"));
assertThat(exception).isExactlyInstanceOf(DuplicateKeyException.class);
exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new R2dbcDataIntegrityViolationException("reason", "23000", 1));
assertThat(exception).as("Oracle").isExactlyInstanceOf(DuplicateKeyException.class);
exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new R2dbcDataIntegrityViolationException("reason", "23000", 301));
assertThat(exception).as("SAP HANA").isExactlyInstanceOf(DuplicateKeyException.class);
exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new R2dbcDataIntegrityViolationException("reason", "23000", 1062));
assertThat(exception).as("MySQL/MariaDB").isExactlyInstanceOf(DuplicateKeyException.class);
exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new R2dbcDataIntegrityViolationException("reason", "23000", 2601));
assertThat(exception).as("MS SQL Server").isExactlyInstanceOf(DuplicateKeyException.class);
exception = ConnectionFactoryUtils.convertR2dbcException("", "",
new R2dbcDataIntegrityViolationException("reason", "23000", 2627));
assertThat(exception).as("MS SQL Server").isExactlyInstanceOf(DuplicateKeyException.class);
} }
@Test @Test

Loading…
Cancel
Save