5

Below is my Code:

void deleteTranslationIfUpdated(Stream<MediaTranslation> from, Stream<MediaTranslationDTO> data) {
    Stream<MediaTranslation> newLogos = data
        .map(mediaTranslationMapper::mapToEntity)
        .collect(Collectors.toList())
        .stream();

    from.filter(e ->
        newLogos.noneMatch(it ->
            Objects.equals(e.getLang(), it.getLang()) && Objects.equals(e.getValue().getLink(), it.getValue().getLink())))
        .map(MediaTranslation::getValue)
        .map(Media::getLink)
        .filter(this::isNotHttpLink)
        .forEach(storageService::delete);
}

Above function is called from the below function:

@Secured({AuthoritiesConstants.USER})
public BrandDTO update(String id, BrandDTO data) throws EntityNotFound {
    log.debug("Request to update Brand : {} with {}", id, data);
    return Optional.ofNullable(brandRepository.findOne(id))
        .map(from -> {
            mediaService.deleteTranslationIfUpdated(from.getLogo().stream(), data.getLogo().stream());
            return from;
        })
        .map(target -> brandMapper.updateFromDto(data, target))
        .map(brandRepository::save)
        .map(brandMapper::mapToDto)
        .map(this::copyCategoriesInZone)
        .orElseThrow(EntityNotFound::new);
}

And whenever I do so, I get the below error:

java.lang.IllegalStateException: stream has already been operated upon or closed at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229) at java.util.stream.ReferencePipeline.noneMatch(ReferencePipeline.java:459) at com.nearbuy.mall.service.MediaService.lambda$deleteTranslationIfUpdated$4(MediaService.java:62)

I get the above error on newLogos.noneMatch.....:(

I'm not sure why.

Eran
  • 387,369
  • 54
  • 702
  • 768
Prashanth Kumar B
  • 566
  • 10
  • 25

1 Answers1

6

Your second stream pipeline attempts to process the newLogos Stream multiple times. This is not possible. A stream can only be processed once.

You will have to re-create that stream for each execution of from.filter(), or find a different way to achieve what you are trying to do.

One thing you can do is:

List<MediaTranslation> newLogos = data
        .map(mediaTranslationMapper::mapToEntity)
        .collect(Collectors.toList());

Now, newLogos is a List, so it can be re-used.

Replace newLogos with newLogos.stream() in the second stream pipeline.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • 1
    I don't understand the moderation on the Java tag: one reason why I stopped answering Java questions. This is a useful answer to a useful question. @UnelectedJavaModerators: please don't damage the Stack Overflow Java knowledge base by deleting answers that are at best linked in the most tenuous of ways to another answer. – Bathsheba Nov 13 '20 at 09:49
  • @Bathsheba You should resume answering Java questions. Don't let self appointed moderators decide for you. A deleted post can just as easily be un-deleted. – Eran Nov 15 '20 at 10:07