I have a a concurrency issue I tried to solve with a while loop that attempts to save an entity multiple times until it hits some max retry count. I'd like to avoid talking about whether or not there are other ways to solve this problem. I have other Stackoverflow posts about that. :) Long story short: there's a unique constraint on a column that is derived and includes a numeric portion that keeps incrementing to avoid collisions. In a loop, I:
All of this seems to work except when the loop goes back to step 1 and tries to select, I get:
17:20:46,111 INFO [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] (http-localhost/127.0.0.1:8080-3) HHH000010: On release of batch it still contained JDBC statements
17:20:46,111 INFO [my.Class] (http-localhost/127.0.0.1:8080-3) MESSAGE="Failed to save to database. Will retry (retry count now at: 9) Exception: could not execute statement; SQL [n/a]; constraint [SCHEMA_NAME.UNIQUE_CONSTRAINT_NAME]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"
And a new Exception is caught. It seems like the first flush that causes the unique constraint violation and throws the DataAccessException
doesn't clear the entity manager's batch. What's the appropriate way to deal with this? I'm using Spring with JPA and don't have direct access to the entity manager. I guess I could inject it if I need it but that's a painful solution to this problem.
You cannot do that - once you flush something and it fails and an exception is thrown, the transaction will be marked as roll back. That means it doesnt matter that you catch the exception and proceed, you'll end up with a rollback.
Actually it doesnt matter at all what exception was thrown - by default Spring's transaction manager will rollback on every unchecked exception.
You can overcome it by specifically defining a noRollbackFor
on the @Transactional
annotation (providing you are using annotation driver transactions)
Edit - it also won't help you in case of this constraint violation, since the transaction will be probably marked as rollback at the database level.
I found this question getting same error. In my case the problem was caused by weird combination of trigger and row lock (see PSQLException and lock issue when trigger added on table). However it took some time to discover this error is just consequence of primary error, not the cause. When Hibernate flushes session and some constraint violation happens, it receives some JDBC exception and in the finally block it tries to call abortBatch
. When any statement remains in session, Hibernate emits this warning, though the actual error should be search for somewhere before.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With