0

My processor return a List of Object but I don't find a solution to override the MongoItemWriter to write some List of object and not object.

I tried this. My processor :

 @Override
  public List<PlaqueLueEntity> process(PlaqueSousSurveillanceEntity item) {
    log.trace("Traitement d'une entrée PlaqueSousSurveillanceEntity: {}", item);

    List<PlaqueLue> rapprochements = this.rapprochementUseCase.findRapprochementByPlaque(item.getPlaque());
    if (rapprochements.isEmpty()) {
      return null;
    }
    for (PlaqueLue rapprochement : rapprochements) {
      rapprochement.setRapprochement(true);
      rapprochement.setHorodatageRapprochement(LocalDateTime.now());
    }
    List<PlaqueLueEntity> plaqueLueEntities =
        rapprochements.stream().map(this.plateDetectionMapper::plateDetectionToPlateDetectionEntity).toList();
    return plaqueLueEntities;
  }

My writer

public class RapprochementMongoWriter<T> extends MongoItemWriter<List<T>> {
  private MongoOperations template;
  private MongoItemWriter<T> delegate;

  @Override
  public void write(final List<? extends List<T>> lists) throws Exception {
    for (final List<T> list : lists) {
      delegate.write(list);
    }
  }
  @Bean
  public MongoItemWriter<List<PlaqueLueEntity>> writer(MongoTemplate mongoTemplate,
      BatchConfigurationProperties batchConfigurationProperties) {
    MongoItemWriter<List<PlaqueLueEntity>> writer = new MongoItemWriter<>();
    writer.setTemplate(mongoTemplate);
    writer.setCollection(String.valueOf(CollectionEnum.COLLECTION.PLAQUE_LUE));
    return writer;
  }

And I defined in my BatchConfiguration:

  @Bean
  public MongoItemWriter<List<PlaqueLueEntity>> rapprochementWriter() {
    return new RapprochementMongoWriter().writer(mongoTemplate, batchConfigurationProperties);
  }

But before I can debug on my writer I got this error:

class org.bson.Document cannot be cast to class java.util.Collection (org.bson.Document is in unnamed module of loader 'app'; java.util.Collection is in module java.base of loader 'bootstrap')

And : Attempt to update step execution id=1 with wrong version (1), where current version is 2

jenoh
  • 165
  • 3
  • 17

1 Answers1

1

I don't find a solution to override the MongoItemWriter to write some List of object and not object.

The way you defined your custom item writer is correct:

public class RapprochementMongoWriter<T> extends MongoItemWriter<List<T>> {

   private MongoItemWriter<T> delegate;

   //...

}

However, you should not call the delegate for each list like this:

  @Override
  public void write(final List<? extends List<T>> lists) throws Exception {
    for (final List<T> list : lists) {
      delegate.write(list);
    }
  }

What you should do instead is "flatten" the items in a single list and call the delegate once, something like this:

  @Override
  public void write(final List<? extends List<T>> lists) throws Exception {
    List<T> flatList = new ArrayList();
    for (final List<T> list : lists) {
       for (T item: list) {
          flatList.add(item);
       }
    }
    delegate.write(flatList);
  }

Please note that I did not compile that snippet, so I will let you adapt it if needed, but you got the idea.

Mahmoud Ben Hassine
  • 28,519
  • 3
  • 32
  • 50