Since #199, SQL failures translate to Spring's DataAccessException hierarchy, but Storm's semantic exceptions — OptimisticLockException, NoResultException, NonUniqueResultException — are thrown by Storm's own logic outside the mapper's reach and stay Storm-typed in every composition. Spring's JPA integration translates its equivalents (OptimisticLockingFailureException, EmptyResultDataAccessException, IncorrectResultSizeDataAccessException), and retry setups keyed on OptimisticLockingFailureException do not see Storm's optimistic-lock conflicts.
A custom ExceptionMapper cannot fix this today: those exceptions never reach the mapper, so core routing is the only path to parity. The likely design: make the mapper the single choke point for every PersistenceException-family failure raised in template and repository operations — behavior-neutral for the default mapper, which passes PersistenceException subtypes through unchanged. The throw sites include interface default methods (Query.getSingleResult and friends), so impl-level overrides are needed in both language stacks.
Deferred from 1.13 deliberately: the docs describe the boundary (database-reported failures translate, Storm-detected failures stay Storm-typed) and the retry recipe lists both exception families. Demand decides the priority.
Since #199, SQL failures translate to Spring's DataAccessException hierarchy, but Storm's semantic exceptions —
OptimisticLockException,NoResultException,NonUniqueResultException— are thrown by Storm's own logic outside the mapper's reach and stay Storm-typed in every composition. Spring's JPA integration translates its equivalents (OptimisticLockingFailureException,EmptyResultDataAccessException,IncorrectResultSizeDataAccessException), and retry setups keyed onOptimisticLockingFailureExceptiondo not see Storm's optimistic-lock conflicts.A custom
ExceptionMappercannot fix this today: those exceptions never reach the mapper, so core routing is the only path to parity. The likely design: make the mapper the single choke point for everyPersistenceException-family failure raised in template and repository operations — behavior-neutral for the default mapper, which passesPersistenceExceptionsubtypes through unchanged. The throw sites include interface default methods (Query.getSingleResultand friends), so impl-level overrides are needed in both language stacks.Deferred from 1.13 deliberately: the docs describe the boundary (database-reported failures translate, Storm-detected failures stay Storm-typed) and the retry recipe lists both exception families. Demand decides the priority.