spring-projects / spring-projects/spring-modulith

Archiving event completion is not working in 2.0 M3

Open
#1,392 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

in: event publication registry meta: waiting for feedback
Dominant language
Java
Stars
1.2k
Forks
222
PR merge metrics
No merged PRs in 30d

Description

After Upgrading to Spring Modulith 2.0.0-M3

it is failing with unable to delete, but it is working with completion-mode UPDATE

2025-10-11T23:08:29.996+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] c.e.outboxpattern.config.LoggingAspect   : Enter: com.example.outboxpattern.order.internal.OrderController.createOrder()
2025-10-11T23:08:30.008+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] c.e.outboxpattern.config.LoggingAspect   : Enter: com.example.outboxpattern.order.internal.OrderService.saveOrder()
2025-10-11T23:08:30.010+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] c.e.outboxpattern.config.LoggingAspect   : Enter: com.example.outboxpattern.order.internal.OrderMapper.toEntity()
2025-10-11T23:08:30.012+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] c.e.outboxpattern.config.LoggingAspect   : Exit: com.example.outboxpattern.order.internal.OrderMapper.toEntity(). Time taken: 1 millis
2025-10-11T23:08:30.145+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] c.e.outboxpattern.config.LoggingAspect   : Enter: com.example.outboxpattern.order.internal.OrderMapper.toResponse()
2025-10-11T23:08:30.146+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] c.e.outboxpattern.config.LoggingAspect   : Exit: com.example.outboxpattern.order.internal.OrderMapper.toResponse(). Time taken: 1 millis
2025-10-11T23:08:30.153+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] .s.m.e.c.DefaultEventPublicationRegistry : Registering publication of com.example.outboxpattern.order.OrderRecord for com.example.outboxpattern.producer.EventProducer.onOrderResponseEvent(com.example.outboxpattern.order.OrderRecord).
2025-10-11T23:08:30.176+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] .s.m.e.c.DefaultEventPublicationRegistry : Registering publication of com.example.outboxpattern.order.OrderRecord for org.springframework.modulith.events.support.DelegatingEventExternalizer.externalize(java.lang.Object).
2025-10-11T23:08:30.187+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] actionalApplicationListenerMethodAdapter : Registered transaction synchronization for org.springframework.context.PayloadApplicationEvent[source=org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext@fd2033e, started on Sat Oct 11 23:07:33 IST 2025]
2025-10-11T23:08:30.188+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] c.e.outboxpattern.config.LoggingAspect   : Exit: com.example.outboxpattern.order.internal.OrderService.saveOrder(). Time taken: 179 millis
2025-10-11T23:08:30.206+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [omcat-handler-0] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] c.e.outboxpattern.config.LoggingAspect   : Exit: com.example.outboxpattern.order.internal.OrderController.createOrder(). Time taken: 208 millis
2025-10-11T23:08:30.276+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-1] [68ea961537f09455246b5646c60bbb0d-c7dabbd222478923] c.e.o.producer.EventProducer             : Received Event :OrderRecord[id=1, orderedDate=2025-10-11T23:08:30.010382700, status=CREATED, orderItems=[OrderItemRecord[productCode=P004, productPrice=100, quantity=10]]]
2025-10-11T23:08:30.280+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-1] [68ea961537f09455246b5646c60bbb0d-c7dabbd222478923] c.e.o.producer.EventProducer             : Started publishing for order 1
2025-10-11T23:08:30.282+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [         task-1] [68ea961537f09455246b5646c60bbb0d-c7dabbd222478923] .s.m.e.c.DefaultEventPublicationRegistry : Marking publication of event com.example.outboxpattern.order.OrderRecord to listener com.example.outboxpattern.producer.EventProducer.onOrderResponseEvent(com.example.outboxpattern.order.OrderRecord) completed.
2025-10-11T23:08:30.283+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] o.s.m.e.s.EventExternalizationSupport    : Externalizing event of type class com.example.outboxpattern.order.OrderRecord to order-created::#{id()}.
2025-10-11T23:08:30.319+05:30 ERROR 5928 --- [spring-modulith-outbox-pattern] [         task-1] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] .a.i.SimpleAsyncUncaughtExceptionHandler : Unexpected exception occurred invoking async method: void com.example.outboxpattern.producer.EventProducer.onOrderResponseEvent(com.example.outboxpattern.order.OrderRecord)

org.springframework.dao.InvalidDataAccessApiUsageException: Entity may not be null
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:365)
	at org.springframework.orm.jpa.hibernate.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:112)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:199)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:554)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:346)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:157)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:719)
	at org.springframework.modulith.events.jpa.JpaEventPublicationRepository$$SpringCGLIB$$0.markCompleted(<generated>)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.lambda$markCompleted$4(DefaultEventPublicationRegistry.java:137)
	at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
	at java.base/java.util.Optional.ifPresentOrElse(Optional.java:196)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.propagateStateTransition(DefaultEventPublicationRegistry.java:353)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.propagateStateTransitionAndConclude(DefaultEventPublicationRegistry.java:346)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.markCompleted(DefaultEventPublicationRegistry.java:137)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:158)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:369)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:719)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry$$SpringCGLIB$$0.markCompleted(<generated>)
	at org.springframework.modulith.events.support.CompletionRegisteringAdvisor$CompletionRegisteringMethodInterceptor.registerStateTransition(CompletionRegisteringAdvisor.java:228)
	at org.springframework.modulith.events.support.CompletionRegisteringAdvisor$CompletionRegisteringMethodInterceptor.invoke(CompletionRegisteringAdvisor.java:196)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.modulith.observability.support.ModuleEntryInterceptor.invoke(ModuleEntryInterceptor.java:132)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:112)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:328)
	at io.micrometer.context.ContextSnapshot.lambda$wrap$0(ContextSnapshot.java:91)
	at java.base/java.lang.VirtualThread.run(VirtualThread.java:456)
Caused by: java.lang.IllegalArgumentException: Entity may not be null
	at org.hibernate.event.spi.DeleteEvent.<init>(DeleteEvent.java:28)
	at org.hibernate.internal.SessionImpl.remove(SessionImpl.java:2359)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:317)
	at jdk.proxy3/jdk.proxy3.$Proxy191.remove(Unknown Source)
	at org.springframework.modulith.events.jpa.JpaEventPublicationRepository.markCompleted(JpaEventPublicationRepository.java:283)
	at org.springframework.modulith.events.core.EventPublicationRepository.markCompleted(EventPublicationRepository.java:67)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:158)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:135)
	... 28 common frames omitted

2025-10-11T23:08:30.359+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] o.a.kafka.common.config.AbstractConfig   : ProducerConfig values: 
	acks = -1
	batch.size = 16384
	bootstrap.servers = [localhost:9092]
	buffer.memory = 33554432
	client.dns.lookup = use_all_dns_ips
	client.id = spring-modulith-outbox-pattern-producer-1
	compression.gzip.level = -1
	compression.lz4.level = 9
	compression.type = none
	compression.zstd.level = 3
	connections.max.idle.ms = 540000
	delivery.timeout.ms = 120000
	enable.idempotence = true
	enable.metrics.push = true
	interceptor.classes = []
	key.serializer = class org.apache.kafka.common.serialization.StringSerializer
	linger.ms = 5
	max.block.ms = 60000
	max.in.flight.requests.per.connection = 5
	max.request.size = 1048576
	metadata.max.age.ms = 300000
	metadata.max.idle.ms = 300000
	metadata.recovery.rebootstrap.trigger.ms = 300000
	metadata.recovery.strategy = rebootstrap
	metric.reporters = [org.apache.kafka.common.metrics.JmxReporter]
	metrics.num.samples = 2
	metrics.recording.level = INFO
	metrics.sample.window.ms = 30000
	partitioner.adaptive.partitioning.enable = true
	partitioner.availability.timeout.ms = 0
	partitioner.class = null
	partitioner.ignore.keys = false
	receive.buffer.bytes = 32768
	reconnect.backoff.max.ms = 1000
	reconnect.backoff.ms = 50
	request.timeout.ms = 30000
	retries = 2147483647
	retry.backoff.max.ms = 1000
	retry.backoff.ms = 100
	sasl.client.callback.handler.class = null
	sasl.jaas.config = null
	sasl.kerberos.kinit.cmd = /usr/bin/kinit
	sasl.kerberos.min.time.before.relogin = 60000
	sasl.kerberos.service.name = null
	sasl.kerberos.ticket.renew.jitter = 0.05
	sasl.kerberos.ticket.renew.window.factor = 0.8
	sasl.login.callback.handler.class = null
	sasl.login.class = null
	sasl.login.connect.timeout.ms = null
	sasl.login.read.timeout.ms = null
	sasl.login.refresh.buffer.seconds = 300
	sasl.login.refresh.min.period.seconds = 60
	sasl.login.refresh.window.factor = 0.8
	sasl.login.refresh.window.jitter = 0.05
	sasl.login.retry.backoff.max.ms = 10000
	sasl.login.retry.backoff.ms = 100
	sasl.mechanism = GSSAPI
	sasl.oauthbearer.assertion.algorithm = RS256
	sasl.oauthbearer.assertion.claim.aud = null
	sasl.oauthbearer.assertion.claim.exp.seconds = 300
	sasl.oauthbearer.assertion.claim.iss = null
	sasl.oauthbearer.assertion.claim.jti.include = false
	sasl.oauthbearer.assertion.claim.nbf.seconds = 60
	sasl.oauthbearer.assertion.claim.sub = null
	sasl.oauthbearer.assertion.file = null
	sasl.oauthbearer.assertion.private.key.file = null
	sasl.oauthbearer.assertion.private.key.passphrase = null
	sasl.oauthbearer.assertion.template.file = null
	sasl.oauthbearer.client.credentials.client.id = null
	sasl.oauthbearer.client.credentials.client.secret = null
	sasl.oauthbearer.clock.skew.seconds = 30
	sasl.oauthbearer.expected.audience = null
	sasl.oauthbearer.expected.issuer = null
	sasl.oauthbearer.header.urlencode = false
	sasl.oauthbearer.jwks.endpoint.refresh.ms = 3600000
	sasl.oauthbearer.jwks.endpoint.retry.backoff.max.ms = 10000
	sasl.oauthbearer.jwks.endpoint.retry.backoff.ms = 100
	sasl.oauthbearer.jwks.endpoint.url = null
	sasl.oauthbearer.jwt.retriever.class = class org.apache.kafka.common.security.oauthbearer.DefaultJwtRetriever
	sasl.oauthbearer.jwt.validator.class = class org.apache.kafka.common.security.oauthbearer.DefaultJwtValidator
	sasl.oauthbearer.scope = null
	sasl.oauthbearer.scope.claim.name = scope
	sasl.oauthbearer.sub.claim.name = sub
	sasl.oauthbearer.token.endpoint.url = null
	security.protocol = PLAINTEXT
	security.providers = null
	send.buffer.bytes = 131072
	socket.connection.setup.timeout.max.ms = 30000
	socket.connection.setup.timeout.ms = 10000
	ssl.cipher.suites = null
	ssl.enabled.protocols = [TLSv1.2, TLSv1.3]
	ssl.endpoint.identification.algorithm = https
	ssl.engine.factory.class = null
	ssl.key.password = null
	ssl.keymanager.algorithm = SunX509
	ssl.keystore.certificate.chain = null
	ssl.keystore.key = null
	ssl.keystore.location = null
	ssl.keystore.password = null
	ssl.keystore.type = JKS
	ssl.protocol = TLSv1.3
	ssl.provider = null
	ssl.secure.random.implementation = null
	ssl.trustmanager.algorithm = PKIX
	ssl.truststore.certificates = null
	ssl.truststore.location = null
	ssl.truststore.password = null
	ssl.truststore.type = JKS
	transaction.timeout.ms = 60000
	transaction.two.phase.commit.enable = false
	transactional.id = null
	value.serializer = class org.apache.kafka.common.serialization.ByteArraySerializer

2025-10-11T23:08:30.421+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] o.a.k.c.t.i.KafkaMetricsCollector        : initializing Kafka metrics collector
2025-10-11T23:08:30.453+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] o.a.k.clients.producer.KafkaProducer     : [Producer clientId=spring-modulith-outbox-pattern-producer-1] Instantiated an idempotent producer.
2025-10-11T23:08:30.553+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] o.a.kafka.common.config.AbstractConfig   : These configurations '[spring.json.add.type.headers]' were supplied but are not used yet.
2025-10-11T23:08:30.558+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] o.a.kafka.common.utils.AppInfoParser     : Kafka version: 4.1.0
2025-10-11T23:08:30.559+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] o.a.kafka.common.utils.AppInfoParser     : Kafka commitId: 13f70256db3c994c
2025-10-11T23:08:30.559+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] o.a.kafka.common.utils.AppInfoParser     : Kafka startTimeMs: 1760204310554
2025-10-11T23:08:31.083+05:30  WARN 5928 --- [spring-modulith-outbox-pattern] [tern-producer-1] [                                                 ] org.apache.kafka.clients.NetworkClient   : [Producer clientId=spring-modulith-outbox-pattern-producer-1] The metadata response from the cluster reported a recoverable issue with correlation id 1 : {order-created=UNKNOWN_TOPIC_OR_PARTITION}
2025-10-11T23:08:31.085+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [tern-producer-1] [                                                 ] org.apache.kafka.clients.Metadata        : [Producer clientId=spring-modulith-outbox-pattern-producer-1] Cluster ID: 4L6g3nShT-eMCtK--X86sw
2025-10-11T23:08:31.208+05:30  INFO 5928 --- [spring-modulith-outbox-pattern] [tern-producer-1] [                                                 ] o.a.k.c.p.internals.TransactionManager   : [Producer clientId=spring-modulith-outbox-pattern-producer-1] ProducerId set to 0 with epoch 0
2025-10-11T23:08:31.246+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [tern-producer-1] [                                                 ] .s.m.e.c.DefaultEventPublicationRegistry : Marking publication of event com.example.outboxpattern.order.OrderRecord to listener org.springframework.modulith.events.support.DelegatingEventExternalizer.externalize(java.lang.Object) completed.
2025-10-11T23:08:31.254+05:30 DEBUG 5928 --- [spring-modulith-outbox-pattern] [tern-producer-1] [                                                 ] r$CompletionRegisteringMethodInterceptor : Invocation of listener public java.util.concurrent.CompletableFuture org.springframework.modulith.events.support.DelegatingEventExternalizer.externalize(java.lang.Object) failed. Leaving event publication uncompleted.

java.util.concurrent.CompletionException: org.springframework.dao.InvalidDataAccessApiUsageException: Entity may not be null
	at java.base/java.util.concurrent.CompletableFuture.wrapInCompletionException(CompletableFuture.java:323)
	at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:359)
	at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:364)
	at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:670)
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:531)
	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2206)
	at org.springframework.kafka.core.KafkaTemplate.lambda$buildCallback$0(KafkaTemplate.java:902)
	at org.springframework.kafka.core.DefaultKafkaProducerFactory$CloseSafeProducer$1.onCompletion(DefaultKafkaProducerFactory.java:1119)
	at org.apache.kafka.clients.producer.KafkaProducer$AppendCallbacks.onCompletion(KafkaProducer.java:1592)
	at org.apache.kafka.clients.producer.internals.ProducerBatch.completeFutureAndFireCallbacks(ProducerBatch.java:309)
	at org.apache.kafka.clients.producer.internals.ProducerBatch.done(ProducerBatch.java:273)
	at org.apache.kafka.clients.producer.internals.ProducerBatch.complete(ProducerBatch.java:219)
	at org.apache.kafka.clients.producer.internals.Sender.completeBatch(Sender.java:749)
	at org.apache.kafka.clients.producer.internals.Sender.completeBatch(Sender.java:720)
	at org.apache.kafka.clients.producer.internals.Sender.lambda$handleProduceResponse$2(Sender.java:623)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
	at org.apache.kafka.clients.producer.internals.Sender.lambda$handleProduceResponse$3(Sender.java:597)
	at java.base/java.lang.Iterable.forEach(Iterable.java:75)
	at org.apache.kafka.clients.producer.internals.Sender.handleProduceResponse(Sender.java:597)
	at org.apache.kafka.clients.producer.internals.Sender.lambda$sendProduceRequest$9(Sender.java:909)
	at org.apache.kafka.clients.ClientResponse.onComplete(ClientResponse.java:154)
	at org.apache.kafka.clients.NetworkClient.completeResponses(NetworkClient.java:669)
	at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:661)
	at org.apache.kafka.clients.producer.internals.Sender.runOnce(Sender.java:340)
	at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:242)
	at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Entity may not be null
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:365)
	at org.springframework.orm.jpa.hibernate.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:112)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:199)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:554)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:346)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:157)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:719)
	at org.springframework.modulith.events.jpa.JpaEventPublicationRepository$$SpringCGLIB$$0.markCompleted(<generated>)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.lambda$markCompleted$4(DefaultEventPublicationRegistry.java:137)
	at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
	at java.base/java.util.Optional.ifPresentOrElse(Optional.java:196)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.propagateStateTransition(DefaultEventPublicationRegistry.java:353)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.propagateStateTransitionAndConclude(DefaultEventPublicationRegistry.java:346)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.markCompleted(DefaultEventPublicationRegistry.java:137)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:158)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:369)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:719)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry$$SpringCGLIB$$0.markCompleted(<generated>)
	at org.springframework.modulith.events.support.CompletionRegisteringAdvisor$CompletionRegisteringMethodInterceptor.registerStateTransition(CompletionRegisteringAdvisor.java:228)
	at org.springframework.modulith.events.support.CompletionRegisteringAdvisor$CompletionRegisteringMethodInterceptor.lambda$invoke$0(CompletionRegisteringAdvisor.java:180)
	at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:667)
	... 22 common frames omitted
Caused by: java.lang.IllegalArgumentException: Entity may not be null
	at org.hibernate.event.spi.DeleteEvent.<init>(DeleteEvent.java:28)
	at org.hibernate.internal.SessionImpl.remove(SessionImpl.java:2359)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:317)
	at jdk.proxy3/jdk.proxy3.$Proxy191.remove(Unknown Source)
	at org.springframework.modulith.events.jpa.JpaEventPublicationRepository.markCompleted(JpaEventPublicationRepository.java:283)
	at org.springframework.modulith.events.core.EventPublicationRepository.markCompleted(EventPublicationRepository.java:67)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:158)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:135)
	... 44 common frames omitted

2025-10-11T23:08:31.256+05:30 ERROR 5928 --- [spring-modulith-outbox-pattern] [         task-2] [68ea961537f09455246b5646c60bbb0d-e7c2ed687cf3e235] actionalApplicationListenerMethodAdapter : Unexpected error occurred in asynchronous listener

java.util.concurrent.CompletionException: org.springframework.dao.InvalidDataAccessApiUsageException: Entity may not be null
	at org.springframework.util.concurrent.FutureUtils.lambda$toSupplier$0(FutureUtils.java:78)
	at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1789)
	at io.micrometer.context.ContextSnapshot.lambda$wrap$0(ContextSnapshot.java:91)
	at java.base/java.lang.VirtualThread.run(VirtualThread.java:456)
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Entity may not be null
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:365)
	at org.springframework.orm.jpa.hibernate.HibernateExceptionTranslator.translateExceptionIfPossible(HibernateExceptionTranslator.java:112)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:199)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:554)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:346)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:157)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:719)
	at org.springframework.modulith.events.jpa.JpaEventPublicationRepository$$SpringCGLIB$$0.markCompleted(<generated>)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.lambda$markCompleted$4(DefaultEventPublicationRegistry.java:137)
	at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
	at java.base/java.util.Optional.ifPresentOrElse(Optional.java:196)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.propagateStateTransition(DefaultEventPublicationRegistry.java:353)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.propagateStateTransitionAndConclude(DefaultEventPublicationRegistry.java:346)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.markCompleted(DefaultEventPublicationRegistry.java:137)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:158)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:369)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:719)
	at org.springframework.modulith.events.core.DefaultEventPublicationRegistry$$SpringCGLIB$$0.markCompleted(<generated>)
	at org.springframework.modulith.events.support.CompletionRegisteringAdvisor$CompletionRegisteringMethodInterceptor.registerStateTransition(CompletionRegisteringAdvisor.java:228)
	at org.springframework.modulith.events.support.CompletionRegisteringAdvisor$CompletionRegisteringMethodInterceptor.lambda$invoke$0(CompletionRegisteringAdvisor.java:180)
	at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:667)
	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:531)
	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2206)
	at org.springframework.kafka.core.KafkaTemplate.lambda$buildCallback$0(KafkaTemplate.java:902)
	at org.springframework.kafka.core.DefaultKafkaProducerFactory$CloseSafeProducer$1.onCompletion(DefaultKafkaProducerFactory.java:1119)
	at org.apache.kafka.clients.producer.KafkaProducer$AppendCallbacks.onCompletion(KafkaProducer.java:1592)
	at org.apache.kafka.clients.producer.internals.ProducerBatch.completeFutureAndFireCallbacks(ProducerBatch.java:309)
	at org.apache.kafka.clients.producer.internals.ProducerBatch.done(ProducerBatch.java:273)
	at org.apache.kafka.clients.producer.internals.ProducerBatch.complete(ProducerBatch.java:219)
	at org.apache.kafka.clients.producer.internals.Sender.completeBatch(Sender.java:749)
	at org.apache.kafka.clients.producer.internals.Sender.completeBatch(Sender.java:720)
	at org.apache.kafka.clients.producer.internals.Sender.lambda$handleProduceResponse$2(Sender.java:623)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
	at org.apache.kafka.clients.producer.internals.Sender.lambda$handleProduceResponse$3(Sender.java:597)
	at java.base/java.lang.Iterable.forEach(Iterable.java:75)
	at org.apache.kafka.clients.producer.internals.Sender.handleProduceResponse(Sender.java:597)
	at org.apache.kafka.clients.producer.internals.Sender.lambda$sendProduceRequest$9(Sender.java:909)
	at org.apache.kafka.clients.ClientResponse.onComplete(ClientResponse.java:154)
	at org.apache.kafka.clients.NetworkClient.completeResponses(NetworkClient.java:669)
	at org.apache.kafka.clients.NetworkClient.poll(NetworkClient.java:661)
	at org.apache.kafka.clients.producer.internals.Sender.runOnce(Sender.java:340)
	at org.apache.kafka.clients.producer.internals.Sender.run(Sender.java:242)
	at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: java.lang.IllegalArgumentException: Entity may not be null
	at org.hibernate.event.spi.DeleteEvent.<init>(DeleteEvent.java:28)
	at org.hibernate.internal.SessionImpl.remove(SessionImpl.java:2359)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:317)
	at jdk.proxy3/jdk.proxy3.$Proxy191.remove(Unknown Source)
	at org.springframework.modulith.events.jpa.JpaEventPublicationRepository.markCompleted(JpaEventPublicationRepository.java:283)
	at org.springframework.modulith.events.core.EventPublicationRepository.markCompleted(EventPublicationRepository.java:67)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:158)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:135)
	... 44 common frames omitted

sample to reproduce : https://github.com/rajadilipkolli/kafka-experiments/tree/main/spring-modulith-outbox-pattern

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with JpaEventPublicationRepository.java at markCompleted(), then trace the completion transition through DefaultEventPublicationRegistry.markCompleted() shown in the stack trace. Reproduce the reported ARCHIVE completion-mode case and compare it with UPDATE. Done means successful listener completion without the Entity may not be null exception and correct removal of the publication.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, spring-boot
Domain
backend, database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.