Skip to content

SimpleReactiveMongoRepository#saveAll does not populate @Id property if it is immutable #3609

Closed
@petitcl

Description

@petitcl

When using the Flux<S> saveAll(Publisher<S> entityStream) method from the SimpleReactiveMongoRepository class, the returned entities do not have their @Id annotated property populated, in the case where the annotated field is immutable.

The @Id annotated property should obviously be populated with the ObjectId generated by mongodb.

This bug does not affect Flux<S> saveAll(Iterable<S> entities) nor Flux<S> insert(Publisher<S> entities). It only occurs if the @Id property is immutable (ie: final and no setter).

I was able to reproduce the bug on the following versions:

  • spring-data-mongodb 3.1.6, spring-data-commons 2.4.6
  • spring-data-mongodb 3.0.7, spring-data-commons 2.3.7
  • spring-data-mongodb 2.2.12, spring-data-commons 2.2.12

Here a sample repository to reproduce this bug: petitcl/spring-data-mongodb-sample-1. This sample shows that the bug occurs for an immutable entity but not for a mutable entity.

After looking at the code of SimpleReactiveMongoRepository in version 2.4.4, it seems to be due to the fact that the original entity reference is returned, instead of the entity returned by the underlying MongoOperations.
This works if the entity is mutable, because the entity reference will be updated with the new id, but it does not work if the entity is immutable, as it would require a new reference with the populated id.

Current Code:

	@Override
	public <S extends T> Flux<S> saveAll(Publisher<S> entityStream) {

		Assert.notNull(entityStream, "The given Publisher of entities must not be null!");

		return Flux.from(entityStream)
			.flatMap(
				entity -> entityInformation.isNew(entity) ?
				mongoOperations.insert(entity, entityInformation.getCollectionName()).then(Mono.just(entity)) :
				mongoOperations.save(entity, entityInformation.getCollectionName()).then(Mono.just(entity))
			);
	}

What I assume it should look like:

	@Override
	public <S extends T> Flux<S> saveAll(Publisher<S> entityStream) {

		Assert.notNull(entityStream, "The given Publisher of entities must not be null!");

		return Flux.from(entityStream)
			.flatMap(
				entity -> entityInformation.isNew(entity) ?
					mongoOperations.insert(entity, entityInformation.getCollectionName()) :
					mongoOperations.save(entity, entityInformation.getCollectionName())
			);
	}

If you validate that this is indeed a bug, I can probably submit a PR to fix it.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions