We are using spring modulith for application events and executed a scheduled job trigger to process incomplete events . The process prints below query
Hibernate:
select
jep1_0.id,
jep1_0.completion_date,
jep1_0.event_type,
jep1_0.listener_id,
jep1_0.publication_date,
jep1_0.serialized_event
from
event_publication jep1_0
where
jep1_0.completion_date is null
and jep1_0.publication_date<?
order by
jep1_0.publication_date
The strange behaviour is that we are getting class cast exception. All our entitities have primary key column as UUID and when we are using JPA we are getting no such issue , But in case of incomplete event publication it goes through entity manager path as in the modulith and breaks when result set id is getting casted to UUID.
We tried multiple ways to have a workaround for this but were unable to do so. This issue has kind of made it a blocker to use spring modulith events effectively.
Kindly have a look at it.
java.lang.ClassCastException: Cannot cast java.lang.String to java.util.UUID
at java.base/java.lang.Class.cast(Class.java:4067) ~[na:na]
at org.postgresql.jdbc.PgResultSet.getObject(PgResultSet.java:3903) ~[postgresql-42.7.3.jar:42.7.3]
at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java) ~[HikariCP-5.0.1.jar:na]
at org.hibernate.type.descriptor.jdbc.UUIDJdbcType$2.doExtract(UUIDJdbcType.java:81) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.type.descriptor.jdbc.BasicExtractor.extract(BasicExtractor.java:44) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.getCurrentRowValue(JdbcValuesResultSetImpl.java:302) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.internal.RowProcessingStateStandardImpl.getJdbcValue(RowProcessingStateStandardImpl.java:119) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.graph.basic.BasicResultAssembler.extractRawValue(BasicResultAssembler.java:52) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.graph.basic.BasicResultAssembler.assemble(BasicResultAssembler.java:59) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.initializeIdentifier(AbstractEntityInitializer.java:374) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.resolveEntityKey(AbstractEntityInitializer.java:351) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.resolveKey(AbstractEntityInitializer.java:293) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.internal.InitializersList.resolveKeys(InitializersList.java:82) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.internal.StandardRowReader.coordinateInitializers(StandardRowReader.java:107) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.sql.results.internal.StandardRowReader.readRow(StandardRowReader.java:86) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.internal.ScrollableResultsImpl.prepareCurrentRow(ScrollableResultsImpl.java:132) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:52) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at org.hibernate.query.internal.ScrollableResultsIterator.hasNext(ScrollableResultsIterator.java:33) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final]
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132) ~[na:na]
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627) ~[na:na]
at org.springframework.modulith.events.jpa.JpaEventPublicationRepository.findIncompletePublicationsPublishedBefore(JpaEventPublicationRepository.java:182) ~[spring-modulith-events-jpa-1.2.1.jar:1.2.1]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.6.jar:6.1.6]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:392) ~[spring-tx-6.1.6.jar:6.1.6]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.modulith.events.jpa.JpaEventPublicationRepository$$SpringCGLIB$$0.findIncompletePublicationsPublishedBefore() ~[spring-modulith-events-jpa-1.2.1.jar:1.2.1]
at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.findIncompletePublicationsOlderThan(DefaultEventPublicationRegistry.java:96) ~[spring-modulith-events-core-1.2.1.jar:1.2.1]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.modulith.events.core.DefaultEventPublicationRegistry$$SpringCGLIB$$0.findIncompletePublicationsOlderThan() ~[spring-modulith-events-core-1.2.1.jar:1.2.1]
at org.springframework.modulith.events.support.PersistentApplicationEventMulticaster.doResubmitUncompletedPublicationsOlderThan(PersistentApplicationEventMulticaster.java:205) ~[spring-modulith-events-core-1.2.1.jar:1.2.1]
at org.springframework.modulith.events.support.PersistentApplicationEventMulticaster.resubmitIncompletePublicationsOlderThan(PersistentApplicationEventMulticaster.java:162) ~[spring-modulith-events-core-1.2.1.jar:1.2.1]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.jobrunr.server.runner.AbstractBackgroundJobRunner$BackgroundJobWorker.invokeJobMethod(AbstractBackgroundJobRunner.java:65) ~[jobrunr-7.2.1.jar:7.2.1]
at** org.jobrunr.server.runner.AbstractBackgroundJobRunner$BackgroundJobWorker.run(AbstractBackgroundJobRunner.java:39) ~[jobrunr-7.2.1.jar:7.2.1]
at org.jobrunr.server.runner.AbstractBackgroundJobRunner.run(AbstractBackgroundJobRunner.java:21) ~[jobrunr-7.2.1.jar:7.2.1]
at org.jobrunr.server.BackgroundJobPerformer.runActualJob(BackgroundJobPerformer.java:95) ~[jobrunr-7.2.1.jar:7.2.1]
at org.jobrunr.server.BackgroundJobPerformer.performJob(BackgroundJobPerformer.java:68) ~[jobrunr-7.2.1.jar:7.2.1]
at org.jobrunr.server.BackgroundJobPerformer.run(BackgroundJobPerformer.java:46) ~[jobrunr-7.2.1.jar:7.2.1]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na]
at java.base/java.lang.VirtualThread.run(VirtualThread.java:329) ~[na:na]
Spring boot dependancy
"org.springframework.boot" version "3.2.5" "io.spring.dependency-management" version "1.1.4"
Modulith Dependancy 'org.springframework.modulith:spring-modulith-starter-core' 'org.springframework.modulith:spring-modulith-events-api'
Modulith BOM org.springframework.modulith:spring-modulith-bom:1.2.1
Used database : GoogleSpanner with postgress , used pgadapter ->
Spanner Details
"com.google.cloud:google-cloud-spanner-pgadapter pgAdapterVersion = "0.33.0" postgresqlVersion = "42.7.3"
We are using spring modulith for application events and executed a scheduled job trigger to process incomplete events . The process prints below query
Hibernate: select jep1_0.id, jep1_0.completion_date, jep1_0.event_type, jep1_0.listener_id, jep1_0.publication_date, jep1_0.serialized_event from event_publication jep1_0 where jep1_0.completion_date is null and jep1_0.publication_date<? order by jep1_0.publication_date The strange behaviour is that we are getting class cast exception. All our entitities have primary key column as UUID and when we are using JPA we are getting no such issue , But in case of incomplete event publication it goes through entity manager path as in the modulith and breaks when result set id is getting casted to UUID.
The repo for pgresultSet section which we found was https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java
We tried multiple ways to have a workaround for this but were unable to do so. This issue has kind of made it a blocker to use spring modulith events effectively.
Kindly have a look at it.
java.lang.ClassCastException: Cannot cast java.lang.String to java.util.UUID at java.base/java.lang.Class.cast(Class.java:4067) ~[na:na] at org.postgresql.jdbc.PgResultSet.getObject(PgResultSet.java:3903) ~[postgresql-42.7.3.jar:42.7.3] at com.zaxxer.hikari.pool.HikariProxyResultSet.getObject(HikariProxyResultSet.java) ~[HikariCP-5.0.1.jar:na] at org.hibernate.type.descriptor.jdbc.UUIDJdbcType$2.doExtract(UUIDJdbcType.java:81) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.type.descriptor.jdbc.BasicExtractor.extract(BasicExtractor.java:44) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.jdbc.internal.JdbcValuesResultSetImpl.getCurrentRowValue(JdbcValuesResultSetImpl.java:302) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.internal.RowProcessingStateStandardImpl.getJdbcValue(RowProcessingStateStandardImpl.java:119) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.graph.basic.BasicResultAssembler.extractRawValue(BasicResultAssembler.java:52) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.graph.basic.BasicResultAssembler.assemble(BasicResultAssembler.java:59) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.initializeIdentifier(AbstractEntityInitializer.java:374) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.resolveEntityKey(AbstractEntityInitializer.java:351) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.resolveKey(AbstractEntityInitializer.java:293) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.internal.InitializersList.resolveKeys(InitializersList.java:82) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.internal.StandardRowReader.coordinateInitializers(StandardRowReader.java:107) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.sql.results.internal.StandardRowReader.readRow(StandardRowReader.java:86) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.internal.ScrollableResultsImpl.prepareCurrentRow(ScrollableResultsImpl.java:132) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:52) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at org.hibernate.query.internal.ScrollableResultsIterator.hasNext(ScrollableResultsIterator.java:33) ~[hibernate-core-6.4.4.Final.jar:6.4.4.Final] at java.base/java.util.Iterator.forEachRemaining(Iterator.java:132) ~[na:na] at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939) ~[na:na] at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na] at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na] at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575) ~[na:na] at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) ~[na:na] at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616) ~[na:na] at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622) ~[na:na] at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627) ~[na:na] at org.springframework.modulith.events.jpa.JpaEventPublicationRepository.findIncompletePublicationsPublishedBefore(JpaEventPublicationRepository.java:182) ~[spring-modulith-events-jpa-1.2.1.jar:1.2.1] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.6.jar:6.1.6] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.6.jar:6.1.6] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.6.jar:6.1.6] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.6.jar:6.1.6] at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.6.jar:6.1.6] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:392) ~[spring-tx-6.1.6.jar:6.1.6] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.6.jar:6.1.6] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.6.jar:6.1.6] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.6.jar:6.1.6] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.6.jar:6.1.6] at org.springframework.modulith.events.jpa.JpaEventPublicationRepository$$SpringCGLIB$$0.findIncompletePublicationsPublishedBefore() ~[spring-modulith-events-jpa-1.2.1.jar:1.2.1]
at org.springframework.modulith.events.core.DefaultEventPublicationRegistry.findIncompletePublicationsOlderThan(DefaultEventPublicationRegistry.java:96) ~[spring-modulith-events-core-1.2.1.jar:1.2.1]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:716) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.modulith.events.core.DefaultEventPublicationRegistry$$SpringCGLIB$$0.findIncompletePublicationsOlderThan() ~[spring-modulith-events-core-1.2.1.jar:1.2.1]
at org.springframework.modulith.events.support.PersistentApplicationEventMulticaster.doResubmitUncompletedPublicationsOlderThan(PersistentApplicationEventMulticaster.java:205) ~[spring-modulith-events-core-1.2.1.jar:1.2.1]
at org.springframework.modulith.events.support.PersistentApplicationEventMulticaster.resubmitIncompletePublicationsOlderThan(PersistentApplicationEventMulticaster.java:162) ~[spring-modulith-events-core-1.2.1.jar:1.2.1]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.jobrunr.server.runner.AbstractBackgroundJobRunner$BackgroundJobWorker.invokeJobMethod(AbstractBackgroundJobRunner.java:65) ~[jobrunr-7.2.1.jar:7.2.1]
at** org.jobrunr.server.runner.AbstractBackgroundJobRunner$BackgroundJobWorker.run(AbstractBackgroundJobRunner.java:39) ~[jobrunr-7.2.1.jar:7.2.1]
at org.jobrunr.server.runner.AbstractBackgroundJobRunner.run(AbstractBackgroundJobRunner.java:21) ~[jobrunr-7.2.1.jar:7.2.1]
at org.jobrunr.server.BackgroundJobPerformer.runActualJob(BackgroundJobPerformer.java:95) ~[jobrunr-7.2.1.jar:7.2.1]
at org.jobrunr.server.BackgroundJobPerformer.performJob(BackgroundJobPerformer.java:68) ~[jobrunr-7.2.1.jar:7.2.1]
at org.jobrunr.server.BackgroundJobPerformer.run(BackgroundJobPerformer.java:46) ~[jobrunr-7.2.1.jar:7.2.1]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572) ~[na:na]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[na:na]
at java.base/java.lang.VirtualThread.run(VirtualThread.java:329) ~[na:na]