-
Notifications
You must be signed in to change notification settings - Fork 692
Description
Hi, spring-boot migration 3.5.3->3.5.4 causes NPE (spring-data-relational 3.5.2)
this happens in
MappingRelationalConverter.writeValue() because
if (TypeInformation.OBJECT != type) {
was replaced with if (!TypeInformation.OBJECT.equals(type)) {
I have a rather specific app: This app is used for testing purposes. It allows to start several spring-boot based micro-services in a single jvm.
Because of complex hierarchy TypeInformation <-> ClassTypeInformation and dependencies of static objects
the field TypeInformation.OBJECT may have a null value, which causes npe:
java.lang.NullPointerException: Cannot invoke "Object.equals(Object)" because "org.springframework.data.util.TypeInformation.OBJECT" is null
at org.springframework.data.relational.core.conversion.MappingRelationalConverter.writeValue(MappingRelationalConverter.java:705)
at org.springframework.data.jdbc.core.convert.MappingJdbcConverter.writeValue(MappingJdbcConverter.java:214)
at org.springframework.data.jdbc.core.convert.MappingJdbcConverter.writeJdbcValue(MappingJdbcConverter.java:247)
at org.springframework.data.jdbc.repository.query.StringBasedJdbcQuery.writeValue(StringBasedJdbcQuery.java:320)
at org.springframework.data.jdbc.repository.query.StringBasedJdbcQuery.bindParameters(StringBasedJdbcQuery.java:281)
at org.springframework.data.jdbc.repository.query.StringBasedJdbcQuery.execute(StringBasedJdbcQuery.java:230)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:170)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:149)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:380)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at io.opentelemetry.javaagent.instrumentation.spring.data.v1_8.SpringDataInstrumentationModule$RepositoryInterceptor.invoke(SpringDataInstrumentationModule.java:112)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
at jdk.proxy6/jdk.proxy6.$Proxy217.getUIDealsStatistic(Unknown Source)
at foo.baz.service.FooIndex.loadCache(FooIndex.java:61)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130)
at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124)
at io.micrometer.observation.Observation.observe(Observation.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124)
There is a workaround to fix:
add TypeInformation.of(String.class);
as a first statement in main method.
I found a simple option to reproduce the issue:
adding two lines in main method
public static void main(String[] args) {
Object ignore = ClassTypeInformation.COLLECTION;
Object ignore2 = TypeInformation.OBJECT;
// ...