Ich habe herausgefunden, wie ich die NullPointerException (NPE) reproduzieren kann, die ich in der Protokollierung gesehen habe.
Der Stacktrace zeigt auf die Zeile von Stream.toList() -Methode in der findAll()-Methode unten. EventorRepostory ist ein Standard-JpaRepository und toDomainModel ist ein Lombok-Builder für eine Datensatzklasse mit genau denselben Eigenschaften (nicht nullbar).
Was mich so überzeugt hat, ist, dass jpaRepository.findall() das kann Erstellen Sie nur eine NPE-sichere Liste. Die toDomainModel-Methode ist ein Lombok-Builder, der ebenfalls nullsicher sein sollte, sofern er kein Nullobjekt empfängt. Das erste macht das zweite narrensicher, also wie kann toList() hier einen NPE verursachen?
Code: Select all
public List findAll() {
return eventorRepository
.findAll()
.parallelStream()
.map(Eventor::toDomainModel)
.toList();
}
@Entity
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Eventor {
@NotNull
private Integer id;
@Id
private UUID uuid;
private Instant creationDate;
private Location location; //class with @NotNull properties
@Embedded
private EventorState eventorState;
}
Das Ausführen von Tests mit Eigenschaften null oder Objekten null führt z. B. nur aus
Code: Select all
@Test
public void test() {
when(jpaRepository.findAll()).thenReturn(List.of(getEventor()));
service.findAll().forEach(System.out::println);
}
{"timestamp": "2025-01-02T20:47:43.967Z", "level": "FEHLER", "thread": "Scheduling -1“, „logger“: „org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler“, „message“: „Unerwartete Ausnahme beim Aufruf der asynchronen Methode aufgetreten: public void.“ nu.eg.nu.business.services.EventorService.processEventor(java.util.Collection,java.time.Instant)","context":"default","ception="java.lang.NullPointerException: null\n \tat java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(Unknown Source)\n\tat java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unbekannte Quelle)\n\tat java.base/java.lang.reflect.Constructor.newInstance(Unbekannte Quelle)\n\tat java.base/java.util. concurrent.ForkJoinTask.getThrowableException(Unbekannte Quelle)\n\tat java.base/java.util.concurrent.ForkJoinTask.reportException(Unbekannte Quelle)\n\tat java.base/java.util.concurrent.ForkJoinTask.invoke(Unbekannte Quelle)\n\tat java.base/java.util. stream.Nodes.collect(Unknown Source)\n\tat java.base/java.util.stream.ReferencePipeline.evaluateToNode(Unknown Quelle)\n\tat java.base/java.util.stream.AbstractPipeline.evaluate(Unbekannte Quelle)\n\tat java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(Unbekannte Quelle)\n\tat java. base/java.util.stream.ReferencePipeline.toArray(Unbekannte Quelle)\n\tat java.base/java.util.stream.ReferencePipeline.toArray(Unbekannte Quelle)\n\tat java.base/java.util.stream.ReferencePipeline.toList(Unbekannte Quelle)\n\tat nu.eg.numsi.persistence. EventorSqlRepository.findAll(EventorSqlRepository.java:26)\n\tat java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unbekannte Quelle)\n\tat java.base/java.lang.reflect.Method.invoke(Unbekannte Quelle)\n\tat org.springframework.aop.support. AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)\n\tat org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)\n\tat org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720)\n\tat nu.eg.nu.persistence.EventorSqlRepository$$SpringCGLIB$$0.findAll()\n\tat nu.eg.nu.business.services.EventorService.getAllEventor(EventorService.java:22)\n\tat nu.eg.nu.business.services.EventorService.getEventorAsMap(EventorService.java:26)\n\tat nu. zB.nu.business.services.EventorService.getEventorAsMap(EventorService.java:59)\n\tat nu.eg.nu.business.services.EventorService.processEventor(EventorService.java:34)\n\tat java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)\n\tat java.base/java .lang.reflect.Method.invoke(Unbekannte Quelle)\n\tat org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)\n\tat org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)\n\tat org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768)\n\tat org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:113)\n\tat java.base/java.util.concurrent.FutureTask.run(Unknown Source)\n\tat java.base/ java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Quelle)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unbekannte Quelle)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unbekannte Quelle)\n\tat java.base/java.lang.Thread.run(Unbekannte Quelle)\nVerursacht durch: java.lang.NullPointerException: null\n"}
Meine Vermutung ist, dass es parrellelStream oder toList sein könnte, aber ich möchte es zuerst reproduzieren.