Hey folks,
I have an event handler, which creates and/or updates entities using JPA (spring-boot-data-jpa to be precise). Now, it can happen, that Exceptions occur during event handling, which might be resolvable by retry (e.g. locking issues) so I wrote an ErrorHandler, that propagates certain exception, just like the PropagatingErrorHandler
from Axon would do, and registered it for my EventProcessor. So far so good.
In the logs I can verify, that the Exceptions are logged as WARN only and retry seems to work. But in some cases after such an Exception, I am getting another Exception that is related to flushed Hibernate sessions:
2022-01-17 13:26:34.544 EventProcessor[myOwnProjection]-0 [ERROR] [AssertionFailure] - HHH000099: an assertion failure occurred (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in my.own.ExampleEntity entry (don't flush the Session after an exception occurs)org.hibernate.AssertionFailure: null id in my.own.ExampleEntity entry (don't flush the Session after an exception occurs)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:76)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:203)
at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:162)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:229)
at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:93)
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1367)
at org.hibernate.internal.SessionImpl.executeUpdate(SessionImpl.java:1471)
at org.hibernate.query.internal.AbstractProducedQuery.doExecuteUpdate(AbstractProducedQuery.java:1714)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1696)
at org.axonframework.eventhandling.tokenstore.jpa.JpaTokenStore.extendClaim(JpaTokenStore.java:211)
at org.axonframework.eventhandling.TrackingEventProcessor.lambda$null$0(TrackingEventProcessor.java:181)
at org.axonframework.messaging.unitofwork.MessageProcessingContext.notifyHandlers(MessageProcessingContext.java:72)
at org.axonframework.messaging.unitofwork.BatchingUnitOfWork.lambda$notifyHandlers$2(BatchingUnitOfWork.java:155)
at java.base/java.util.ArrayList$Itr.forEachRemaining(ArrayList.java:1033)
at org.axonframework.messaging.unitofwork.BatchingUnitOfWork.notifyHandlers(BatchingUnitOfWork.java:155)
at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.changePhase(AbstractUnitOfWork.java:222)
at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.commitAsRoot(AbstractUnitOfWork.java:83)
at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.commit(AbstractUnitOfWork.java:71)
at org.axonframework.messaging.unitofwork.BatchingUnitOfWork.executeWithResult(BatchingUnitOfWork.java:111)
at org.axonframework.eventhandling.AbstractEventProcessor.processInUnitOfWork(AbstractEventProcessor.java:159)
at org.axonframework.eventhandling.TrackingEventProcessor.processBatch(TrackingEventProcessor.java:462)
at org.axonframework.eventhandling.TrackingEventProcessor.processingLoop(TrackingEventProcessor.java:294)
at org.axonframework.eventhandling.TrackingEventProcessor$TrackingSegmentWorker.run(TrackingEventProcessor.java:1016)
at org.axonframework.eventhandling.TrackingEventProcessor$WorkerLauncher.run(TrackingEventProcessor.java:1162)
at java.base/java.lang.Thread.run(Thread.java:829)
It’s just a rough guess, but could it happen that a RuntimeException
occurs during event processing, which marks the transaction as rollback-only
(you know, because it’s Spring), but Axon still tries to flush at some point during its UnitOfWork handling?
I am pretty clueless at this point, so any input is appreciated.
Cheers,
Stefan