Skip to content

Inconsistent _id Storage Type Between save and saveAll for @MongoId String id #4944

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
initdch opened this issue Apr 10, 2025 · 1 comment
Closed
Assignees
Labels
type: bug A general bug

Comments

@initdch
Copy link

initdch commented Apr 10, 2025

Description

When using Spring Data MongoDB with entities annotated with @MongoId String id, there is an inconsistency in how the _id field is stored in MongoDB depending on whether save or saveAll is used. Specifically, save stores the _id as a String, while saveAll stores it as an ObjectId, even though the ID is not explicitly set in either case.

That even leads to duplication in the DB, since when used saveAll and the update it will convert it to string but creates a duplicated object

Steps to Reproduce

  1. Set up a Spring Boot project with the following dependencies:
    • Spring Boot Starter Data MongoDB
  2. Run the application and observe the output.
  3. Check the DB
package com.example.mongo_bug;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoId;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

@SpringBootApplication
public class MongoBugApplication {

	public static void main(String[] args) {
		SpringApplication.run(MongoBugApplication.class, args);

	}

	@Bean
	public CommandLineRunner commandLineRunner(MyRepository repository) {
		return args -> {
			// Create entities without setting ID
			MyEntity entity1 = new MyEntity();
			entity1.setName("Entity1");
			MyEntity entity2 = new MyEntity();
			entity2.setName("Entity2");

			// Save using save
			repository.save(entity1);

			// Save using saveAll
			repository.saveAll(List.of(entity2));

			// Update the name of entity2 will lead to duplicate
			entity2.setName("UpdatedEntity2");
			repository.save(entity2);

			// Find all entities
			List<MyEntity> allEntities = repository.findAll();
			allEntities.forEach(entity -> System.out.println("Entity ID: " + entity.getId() + ", Name: " + entity.getName()));
		};
	}
}

// Repository interface
interface MyRepository extends MongoRepository<MyEntity, String> {
}

// Entity class
@Document
class MyEntity {
	@MongoId
	private String id;
	private String name;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

Expected Behavior

  • Both save and saveAll store _id as a String in MongoDB when id is null and the field is String.

Actual Behavior

  • save stores _id as a String.
  • saveAll stores _id as an ObjectId.
  • Updating an entity saved with saveAll creates a duplicate due to the type mismatch.
{
  _id: '67f82b6888d11c0743a9097f',
  name: 'Entity1',
  _class: 'com.example.mongo_bug.MyEntity'
}
{
  _id: ObjectId("67f82b6888d11c0743a90980"),
  name: 'Entity2',
  _class: 'com.example.mongo_bug.MyEntity'
}
{
  _id: '67f82b6888d11c0743a90980',
  name: 'UpdatedEntity2',
  _class: 'com.example.mongo_bug.MyEntity'
}

Image

Environment

  • Spring Boot Version: 3.4.4
  • Spring Data MongoDB Version: 4.4.4
  • MongoDB Version: 8.0.6
  • Java Version: temurin-22.0.2
  • Operating System: Ubuntu 24.04.2 LTS

Test Project To Reproduce

mongo-bug.zip

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 10, 2025
@christophstrobl
Copy link
Member

thanks for reporting - we'll look into it

@christophstrobl christophstrobl self-assigned this Apr 11, 2025
@christophstrobl christophstrobl added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Apr 11, 2025
@christophstrobl christophstrobl added this to the 4.3.11 (2024.0.11) milestone Apr 11, 2025
christophstrobl added a commit that referenced this issue Apr 11, 2025
This commit fixes an issue where id properties annotated with MongoId had not been converted into the desired target type when inserting a collection of objects instead a single one.

Resolves: #4944
mp911de pushed a commit that referenced this issue Apr 14, 2025
This commit fixes an issue where id properties annotated with MongoId had not been converted into the desired target type when inserting a collection of objects instead a single one.

Resolves: #4944
Original pull request: #4945
mp911de added a commit that referenced this issue Apr 14, 2025
Initialize MongoId also for reactive insertAll(…).

See: #4944
Original pull request: #4945
mp911de pushed a commit that referenced this issue Apr 14, 2025
This commit fixes an issue where id properties annotated with MongoId had not been converted into the desired target type when inserting a collection of objects instead a single one.

Resolves: #4944
Original pull request: #4945
mp911de added a commit that referenced this issue Apr 14, 2025
Initialize MongoId also for reactive insertAll(…).

See: #4944
Original pull request: #4945
mp911de added a commit that referenced this issue Apr 14, 2025
Initialize MongoId also for reactive insertAll(…).

See: #4944
Original pull request: #4945
christophstrobl added a commit that referenced this issue Apr 14, 2025
This commit fixes an issue where id properties annotated with MongoId had not been converted into the desired target type when inserting a collection of objects instead a single one.

Resolves: #4944
Original pull request: #4945
christophstrobl pushed a commit that referenced this issue Apr 14, 2025
Initialize MongoId also for reactive insertAll(…).

See: #4944
Original pull request: #4945
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants