NullPointerException podczas lambda

0

Moja metoda przyjmuje datę i porównuję ją w specyfikacji

public static Specification<MovieEntity> getFindPredicate(
        final Date fromDate
) {
    return (final Root<MovieEntity> root, final CriteriaQuery<?> cq, final CriteriaBuilder cb) -> {
        final List<Predicate> predicates = new ArrayList<>();

        if (fromDate != null) {
            final Join<MovieEntity, MovieReleaseDate> listReleaseDates = root.join(MovieEntity_.releaseDates);
            final List<Predicate> orPredicates =
                    Stream.of(fromDate)
                            .map(releaseDate -> cb.greaterThanOrEqualTo(listReleaseDates.get(MovieReleaseDate_.date), fromDate))
                            .collect(Collectors.toList());
            predicates.add(cb.or(orPredicates.toArray(new Predicate[orPredicates.size()])));
        }
        return cb.and(predicates.toArray(new Predicate[predicates.size()]));
    };
}

Jednak lambda wyrzuca mi wyjątek (https://zapodaj.net/38349010fb814.png.html) (Z czerwonym tłem debugowany fragment)

java.lang.NullPointerException: null
at org.eclipse.persistence.internal.jpa.querydef.FromImpl.get(FromImpl.java:274) ~[org.eclipse.persistence.jpa-2.7.0.jar:na]
at com.core.jpa.specifications.MovieSpecs.lambda$null$0(MovieSpecs.java:48) ~[classes/:na]
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_144]
at java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:419) ~[na:1.8.0_144]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_144]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_144]
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_144]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_144]
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_144]

Czy ta konstrukcja lambdy jest błędna czy o co chodzi?

0

Przedebuguj sobie z użyciem peek(Consumer) - http://www.java67.com/2016/09/java-8-streampeek-example.html

0

Zacznijmy od posprzątania, bo ja tu widzę zagłębie fakapu.

Co robi to?

 if (fromDate != null) {
            final Join<MovieEntity, MovieReleaseDate> listReleaseDates = root.join(MovieEntity_.releaseDates);
            final List<Predicate> orPredicates =
                    Stream.of(fromDate)
                            .map(releaseDate -> cb.greaterThanOrEqualTo(listReleaseDates.get(MovieReleaseDate_.date), fromDate))
                            .collect(Collectors.toList());
            predicates.add(cb.or(orPredicates.toArray(new Predicate[orPredicates.size()])));
        }

fromDate to pojedyncza wartość. Opakowywanie jej w tego rodzaju strumień nie ma sensu. Lepiej jest opakować w Optional i użyć najpierw map, a następnie zamiast collect użyć kolejnego map, które też uwzględni ten warunek and.

final Join<MovieEntity, MovieReleaseDate> listReleaseDates = root.join(MovieEntity_.releaseDates);

wyrzucić do funkcji Function<Root<MovieEntity>, Join<MovieEntity, MovieReleaseDate>> i wypchnąć poza if-a.

To tak na szybko.

1 użytkowników online, w tym zalogowanych: 0, gości: 1