Skip to content

JPATransactionManager and HibernateJpaDialect is not handling gracefully a org.hibernate.TransactionException #28184

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

Closed
estigma88 opened this issue Mar 15, 2022 · 1 comment
Labels
for: external-project Needs a fix in external project in: data Issues in data modules (jdbc, orm, oxm, tx)

Comments

@estigma88
Copy link

Affects:
Spring Orm: 5.3.14
Spring boot version: 2.6.2
Spring data jpa: 2.6.0
Spring Integration version: 5.5.6

Issue:
Seems like JPATransactionManager and HibernateJpaDialect cannot transform a org.hibernate.TransactionException to the right JPA exception based on the internal SQLException, as you can see in the following stacktrace:

Caused by: org.springframework.dao.CannotAcquireLockException: Failed to lock mutex at 19414b49-c76b-3b77-a05d-3aca07a855aa; nested exception is org.springframework.orm.jpa.JpaSystemException: Unable to commit against JDBC Connection; nested exception is org.hibernate.TransactionException: Unable to commit against JDBC Connection
	at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.rethrowAsLockException(JdbcLockRegistry.java:197)
	at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.tryLock(JdbcLockRegistry.java:262)
	at com.geniussports.geniuslive.ingressmanager.domain.pipeline.ingress.IngressPipelineService.create(IngressPipelineService.kt:35)
	at com.geniussports.geniuslive.ingressmanager.application.adapters.pipeline.ingress.gateway.graphql.PipelineMutationResolver.createFromJSON(PipelineMutationResolver.kt:51)
	at jdk.internal.reflect.GeneratedMethodAccessor254.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
	at com.netflix.graphql.dgs.internal.DgsSchemaProvider.invokeDataFetcher(DgsSchemaProvider.kt:402)
	at com.netflix.graphql.dgs.internal.DgsSchemaProvider.access$invokeDataFetcher(DgsSchemaProvider.kt:64)
	at com.netflix.graphql.dgs.internal.DgsSchemaProvider$createBasicDataFetcher$1.get(DgsSchemaProvider.kt:279)
	at com.netflix.graphql.dgs.metrics.micrometer.DgsGraphQLMetricsInstrumentation$instrumentDataFetcher$1.get(DgsGraphQLMetricsInstrumentation.kt:101)
	at graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation.lambda$instrumentDataFetcher$0(DataLoaderDispatcherInstrumentation.java:86)
	at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:270)
	... 76 more
Caused by: org.springframework.orm.jpa.JpaSystemException: Unable to commit against JDBC Connection; nested exception is org.hibernate.TransactionException: Unable to commit against JDBC Connection
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:331)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
	at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:566)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:743)
	at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:711)
	at org.springframework.cloud.sleuth.instrument.tx.TracePlatformTransactionManager.commit(TracePlatformTransactionManager.java:121)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:654)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:407)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
	at org.springframework.integration.jdbc.lock.DefaultLockRepository$$EnhancerBySpringCGLIB$$29ab5ce4.acquire(<generated>)
	at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.doLock(JdbcLockRegistry.java:268)
	at org.springframework.integration.jdbc.lock.JdbcLockRegistry$JdbcLock.tryLock(JdbcLockRegistry.java:249)
	... 88 more
Caused by: org.hibernate.TransactionException: Unable to commit against JDBC Connection
			3 lines skipped for [org.hibernate]
	at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562)
	... 100 more
Caused by: org.postgresql.util.PSQLException: ERROR: could not serialize access due to read/write dependencies among transactions
  Detail: Reason code: Canceled on identification as a pivot, during commit attempt.
  Hint: The transaction might succeed if retried.
	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2674)
	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2364)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:354)
	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:314)
	at org.postgresql.jdbc.PgConnection.executeTransactionCommand(PgConnection.java:853)
	at org.postgresql.jdbc.PgConnection.commit(PgConnection.java:875)
	at com.zaxxer.hikari.pool.ProxyConnection.commit(ProxyConnection.java:387)
	at com.zaxxer.hikari.pool.HikariProxyConnection.commit(HikariProxyConnection.java)
			1 line skipped for [org.hibernate]

The transformation process should arrive to a CannotAcquireLockException, here, as the error is database serialization related.

I was searching for a way to extend the transform behavior on this line, but, cannot find a way to customize this transformation on the HibernateJpaDialect for that org.hibernate.TransactionException.

Note that I created an issue on Spring Integration and Hibernate, as I think Hibernate is the one who is not throwing the right context exception, however, I would like to be able to customize the behavior somehow in the Spring side.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Mar 16, 2022
@rstoyanchev rstoyanchev added the in: data Issues in data modules (jdbc, orm, oxm, tx) label Apr 25, 2022
@snicoll
Copy link
Member

snicoll commented Nov 24, 2023

@estigma88 unfortunately, if the exception is incorrect, there's nothing we can do about that. You can always override the dialect if you need custom exception handling.

@snicoll snicoll closed this as not planned Won't fix, can't repro, duplicate, stale Nov 24, 2023
@snicoll snicoll added for: external-project Needs a fix in external project and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for: external-project Needs a fix in external project in: data Issues in data modules (jdbc, orm, oxm, tx)
Projects
None yet
Development

No branches or pull requests

4 participants