Skip to content

Conversation

sgflt
Copy link

@sgflt sgflt commented Sep 1, 2025

This fix is related to #29950 and #29699 .

After migration from Spring Boot 2 to Spring Boot 3 spring-jdbc changed behavior and now throws DataIntegrityViolationException instead of DuplicateKeyException.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Sep 1, 2025
@sgflt sgflt changed the base branch from 6.2.x to main September 1, 2025 11:20
@sgflt sgflt force-pushed the informix-DuplicateKeyException-detection-fix branch from a7add32 to 5df704c Compare September 1, 2025 11:22
Signed-off-by: Lukáš Kvídera <kvideral@qwsome.eu>
@sgflt sgflt force-pushed the informix-DuplicateKeyException-detection-fix branch from 5df704c to 1df688a Compare September 1, 2025 11:29
@sbrannen sbrannen added the in: data Issues in data modules (jdbc, orm, oxm, tx) label Sep 1, 2025
@sbrannen sbrannen self-assigned this Sep 1, 2025
@sbrannen sbrannen added the type: enhancement A general enhancement label Sep 1, 2025
@sbrannen sbrannen changed the title Informix duplicate key exception detection fix Detect Informix error codes as DuplicateKeyException Sep 1, 2025
@sbrannen
Copy link
Member

sbrannen commented Sep 1, 2025

Hi @sgflt,

Congratulations on submitting your first PR for the Spring Framework! 👍

This is indeed related to #29950, especially this comment (#29950 (comment)).

In sql-error-codes.xml, we support the following for duplicate keys.

<property name="duplicateKeyCodes">
<value>-239,-268,-6017</value>
</property>

The first two are still documented as error codes for Informix 15.

-239	Could not insert new row - duplicate value in a UNIQUE INDEX
column.

The row that is being inserted (or being updated to have a new primary key)
contains a duplicate value of some row that already exists, in a column or
columns that are constrained to have unique values. Another cause of this
error might be a locking conflict if the table lock mode is page. The new
or updated row is not inserted.

Roll back the current transaction and execute it again without any
duplicate rows or with the locking conflict resolved.

If you are using repeatable read isolation, then the error could be due
to a unique constraint being violated. Refer to error -268.
-268	Unique constraint <constraint-name> violated.

During execution of this statement, a duplicate value was introduced
into a column or columns that a unique constraint protects. The row
with the duplicate value was not allowed into the table (not inserted
or not updated). For IBM Informix Dynamic Server, any changes that this statement
made prior to the discovery of the duplicate value have been rolled back. (The
effects of preceding statements in the transaction, if there were any, remain
in effect. They must be explicitly rolled back or committed.)

This error occurs in a logging database. However, if you are using
repeatable read isolation, error -239 will display instead.

Thus, if we were to make this change, I believe we should do it for -239 and -268.

In addition, we would want to do this not only for SQLStateSQLExceptionTranslator (in spring-jdbc) but also for ConnectionFactoryUtils (in spring-r2dbc), and we would need appropriate tests/assertions in SQLStateSQLExceptionTranslatorTests and ConnectionFactoryUtilsTests, respectively.

We will discuss within the team whether we wish to make these changes to SQLStateSQLExceptionTranslator and ConnectionFactoryUtils, and we will let you know whether to proceed with this PR.


Note, however, that we would only implement this change for 6.2.x and 7.0.

For 6.0.x and 6.1.x, see the recommendations in Upgrading From Spring Framework 5.3.

Spring's default JDBC exception translator is the JDBC 4 based SQLExceptionSubclassTranslator now, detecting JDBC driver subclasses as well as common SQL state indications (without database product name resolution at runtime). As of 6.0.3, this includes a common SQL state check for DuplicateKeyException, addressing a long-standing difference between SQL state mappings and legacy default error code mappings.

For full backwards compatibility with database-specific error codes, consider re-enabling the legacy SQLErrorCodeSQLExceptionTranslator. This translator kicks in for user-provided sql-error-codes.xml files. It can simply pick up Spring's legacy default error code mappings as well when triggered by an empty user-provided file in the root of the classpath.

@sbrannen sbrannen marked this pull request as draft September 1, 2025 13:52
@sbrannen
Copy link
Member

sbrannen commented Sep 2, 2025

We have decided to proceed with this.

@sgflt, please update this PR as outlined below.

Thanks

Thus, if we were to make this change, I believe we should do it for -239 and -268.

In addition, we would want to do this not only for SQLStateSQLExceptionTranslator (in spring-jdbc) but also for ConnectionFactoryUtils (in spring-r2dbc), and we would need appropriate tests/assertions in SQLStateSQLExceptionTranslatorTests and ConnectionFactoryUtilsTests, respectively.

@sbrannen sbrannen added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Sep 2, 2025
@sbrannen sbrannen added this to the 6.2.11 milestone Sep 2, 2025
…ctoryUtils

Signed-off-by: Lukáš Kvídera <kvideral@qwsome.eu>
Signed-off-by: Lukáš Kvídera <kvideral@qwsome.eu>
Signed-off-by: Lukáš Kvídera <kvideral@qwsome.eu>
Signed-off-by: Lukáš Kvídera <kvideral@qwsome.eu>
@sgflt sgflt force-pushed the informix-DuplicateKeyException-detection-fix branch from 808d810 to b7757bf Compare September 3, 2025 04:47
Signed-off-by: Lukáš Kvídera <kvideral@qwsome.eu>
@sgflt sgflt marked this pull request as ready for review September 3, 2025 05:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: waiting-for-feedback We need additional information before we can continue type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants