[CONJ-996] BatchUpdateException doesn't inherited the SQLState & vendorCode from the cause SQL exception Created: 2022-08-01  Updated: 2022-09-05  Resolved: 2022-09-05

Status: Closed
Project: MariaDB Connector/J
Component/s: JDBC compatibility
Affects Version/s: 3.0.6
Fix Version/s: 3.0.8

Type: Bug Priority: Major
Reporter: Luc Willems Assignee: Diego Dupin
Resolution: Fixed Votes: 0
Labels: regression
Environment:

JDK11 , migration issue from spring boot application from 2.5.x to 2.7.x which changes the JDBC driver version from 2.7.5 to 3.0.6
using hibernate 5.6.10


Attachments: PNG File Screenshot_20220801_060315.png    

 Description   

when duplicate entry error is given from the database, a internal java.sql.SQLIntegrityConstraintViolationException is thrown with SQLState="2300" and errorCode=1062.

when running this insert queries in batch mode, this exception is wrapped in BatchUpdateException. This exception doesn't inherited the original SQLState and errorCode from the SQLIntegrityConstraintViolationException.

Hibernate receives the BatchUpdateException and tries to map this to more generic , hibernate specific , ConstraintViolationException
using the SQLStateConversionDelegate class.

This flow worked until upgrade to 3.0.6 because the BatchUpdateException has SQLState=null which cause Hibernate to skip the mapping to ConstraintViolationException. Hibernate use the than "first" active Exception , which is the BatchUpdateException !

from user perspective , we have code to handle duplicate exception which catch the hibernate ConstraintViolationException , as we have generic spring boot Repository based code using different DB vendors.

Attached you see a debug session with BatchUpdateException with SQLState=null and underlying SQLIntegrityConstraintViolationException with valid SQLState and vendorCode

the 2.7.5 JDBC driver the BatchUpdateException is created with same SQLState & errorCode as the original SQLException , so hibernate doesn't need to "deep" investigate the possible chain of causes .

a solution , tested this with some reflection code , is to copy the SQLState & errorCode from the SQLIntegrityConstraintViolationException to BatchUpdateException when creating BatchUpdateException in ExceptionFactory.createBatchUpdate()

return new BatchUpdateException(sqlException.toString(),sqlException.getSQLState(),sqlException.getErrorCode(),updateCounts, sqle)



 Comments   
Comment by Luc Willems [ 2022-08-03 ]

other way is using SQLExeption.setNextException(sqle) because hibernate seems to ignore getCause() and use the SQLException chain via getNextException()

Generated at Thu Feb 08 03:19:51 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.