-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SimpleJdbcInsert (sporadically) does not insert all columns #26486
Comments
In light of that, did you perhaps mean to provide a link to Or are you using |
In any case, it looks like So I'll investigate both. |
Sorry for the confusion. We're actually using SimpleJdbcInsert and I accidently linked to a similar but wrong line in Thanks for investigating! |
Prior to this commit, if an SQLException was thrown while retrieving column metadata from the database, SimpleJdbcInsert would generate an INSERT statement that was syntactically valid but missing columns, which could lead to data silently missing in the database (for nullable columns). This commit fixes this by clearing all collected column metadata if an SQLException is thrown while processing the metadata. The result is that an InvalidDataAccessApiUsageException will be thrown later while generating the INSERT statement. The exception message now contains an additional hint to make use of SimpleJdbcInsert#usingColumns() in order to ensure that all required columns are included in the generated INSERT statement. SimpleJdbcCall can also encounter an SQLException while retrieving column metadata for a stored procedure/function, but an exception is not thrown since a later invocation of the stored procedure/function will likely fail anyway due to missing arguments. Consequently, this commit only improves the warning level log message by including a hint to make use of SimpleJdbcCall#addDeclaredParameter(). Closes gh-26486
The fix has been merged into Feel free to try it out in the latest 5.3.4 and 5.2.13 snapshots. |
Affects: Spring Framework 5.3.3
When using
SimpleJdbcInsert
withoutusingColumns()
, it tries to determine the columns from database metadata. When there is any exception, a warning is logged, but otherwise the exception is ignored:spring-framework/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java
Lines 415 to 419 in 9150980
This is fine as long as the exception occurs before any metadata could be read, because later this will cause an exception when generating the SQL string:
spring-framework/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java
Lines 305 to 306 in 9150980
However, when an
SQLException
occurs incolumns.next()
...spring-framework/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java
Line 390 in 9150980
... after the first column metadata has already been read and added to
this.callParameterMetaData
, it continues with an incomplete list of columns and only inserts these, ignoring any other columns.We have experienced this problem in our system very sporadically, and it's especially dangerous, because
SimpleJdbcInsert.execute()
(as long as there are noNOT NULL
constraints for the columns) returns seemingly successfully, so the transactions are committed with incomplete/corrupted data.It seems like we can work around the problem by calling
usingColumns()
for all uses ofSimpleJdbcInsert
.The text was updated successfully, but these errors were encountered: