WHAT

Spring Data Mongo repositories API -> insert(...) ignores @MongoId annotation with variable type and always auto-generates new ObjectId for the provided entity.

VERSION

org.springframework.boot: 2.7.4 io.spring.dependency-management: 1.0.14.RELEASE

EXPECTED BEHAVIOUR

repository.insert(...) - should create an entity in Mongo DB according to the configuration & variable type of provided @MongoId annotation inputs. In case of the existance of the entity - throw org.springframework.dao.DuplicateKeyException exception.

Issue not reproduced for: io.spring.dependency-management: 1.0.13.RELEASE

CODE SAMPLE

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) { runApplication<DemoApplication>(*args) }

@Service
class UserService(
    private val userRepository: UserRepository
) {
    @PostConstruct
    fun init() {
        val user = User(1, "Test")

        // success: Response -> id == 1, DB -> id == 1
        userRepository.save(user) 

        // success (no error): Response -> id == 1, DB -> id == [auto-gen] new ObjectId()
        userRepository.insert(user) 
    }
}

@Repository
interface UserRepository: MongoRepository<User, Long>

@Document
class User(
    @MongoId val id: Long,
    @Field val name: String
)

RESULTED MONGO DATA

Mongo version: 4.4.13

SpringBoot Spring Data Mongo 2.7.4 - repository insert method ignores @MongoId

Comment From: wilkinsona

Thanks for the report. The version of the dependency management plugin shouldn't make any difference (other than an outside chance that it changes the version of some dependencies). To allow us to see exactly what's happening, can you please provide a complete, yet minimal sample that reproduces the problem? You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue. Unless the problem is specific to Kotlin, the sample should be written in Java so as to minimise possible causes.

Comment From: ishugaliy

@wilkinsona sure. The issue was reproduced for Java as well.

Here you can find a working Java sample that reproduces the issue: https://github.com/ishugaliy/spring-data-bug

Thank you

Comment From: wilkinsona

Thank you. How did you switch to 1.0.13.RELEASE of the dependency management plugin? Changing the version in build.gradle isn't sufficient as the org.springframework.boot plugin depends on 1.0.14.RELEASE and Gradle's version conflict resolution chooses the latest version as shown by buildEnvironment:

./gradlew buildEnvironment

> Task :buildEnvironment

------------------------------------------------------------
Root project 'spring-data-bug'
------------------------------------------------------------

classpath
+--- org.springframework.boot:org.springframework.boot.gradle.plugin:2.7.4
|    \--- org.springframework.boot:spring-boot-gradle-plugin:2.7.4
|         +--- org.springframework.boot:spring-boot-buildpack-platform:2.7.4
|         |    +--- com.fasterxml.jackson.core:jackson-databind:2.13.4
|         |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.13.4
|         |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.13.4
|         |    |    |         +--- com.fasterxml.jackson.core:jackson-annotations:2.13.4 (c)
|         |    |    |         +--- com.fasterxml.jackson.core:jackson-core:2.13.4 (c)
|         |    |    |         +--- com.fasterxml.jackson.core:jackson-databind:2.13.4 (c)
|         |    |    |         \--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.4 (c)
|         |    |    +--- com.fasterxml.jackson.core:jackson-core:2.13.4
|         |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.13.4 (*)
|         |    |    \--- com.fasterxml.jackson:jackson-bom:2.13.4 (*)
|         |    +--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.13.4
|         |    |    +--- com.fasterxml.jackson.core:jackson-core:2.13.4 (*)
|         |    |    +--- com.fasterxml.jackson.core:jackson-databind:2.13.4 (*)
|         |    |    \--- com.fasterxml.jackson:jackson-bom:2.13.4 (*)
|         |    +--- net.java.dev.jna:jna-platform:5.7.0
|         |    |    \--- net.java.dev.jna:jna:5.7.0
|         |    +--- org.apache.commons:commons-compress:1.21
|         |    +--- org.apache.httpcomponents:httpclient:4.5.13
|         |    |    +--- org.apache.httpcomponents:httpcore:4.4.13
|         |    |    \--- commons-codec:commons-codec:1.11
|         |    +--- org.springframework:spring-core:5.3.23
|         |    |    \--- org.springframework:spring-jcl:5.3.23
|         |    \--- org.tomlj:tomlj:1.0.0
|         |         +--- org.antlr:antlr4-runtime:4.7.2
|         |         \--- com.google.code.findbugs:jsr305:3.0.2
|         +--- org.springframework.boot:spring-boot-loader-tools:2.7.4
|         |    +--- org.apache.commons:commons-compress:1.21
|         |    \--- org.springframework:spring-core:5.3.23 (*)
|         +--- io.spring.gradle:dependency-management-plugin:1.0.14.RELEASE
|         +--- org.apache.commons:commons-compress:1.21
|         \--- org.springframework:spring-core:5.3.23 (*)
\--- io.spring.dependency-management:io.spring.dependency-management.gradle.plugin:1.0.13.RELEASE
     \--- io.spring.gradle:dependency-management-plugin:1.0.13.RELEASE -> 1.0.14.RELEASE

(c) - dependency constraint
(*) - dependencies omitted (listed previously)

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed

Comment From: wilkinsona

Investigating further, as far as I can tell the version of the dependency management plugin isn't relevant.

With Spring Boot 2.7.4 the insert succeeds when it should not. With 2.7.3 it fails with the following:

Caused by: com.mongodb.MongoWriteException: Write operation error on server localhost:27017. Write error: WriteError{code=11000, message='E11000 duplicate key error collection: test.user index: _id_ dup key: { _id: 1 }', details={}}.
        at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1018) ~[mongodb-driver-sync-4.6.1.jar:na]
        at com.mongodb.client.internal.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:471) ~[mongodb-driver-sync-4.6.1.jar:na]
        at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:454) ~[mongodb-driver-sync-4.6.1.jar:na]
        at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:448) ~[mongodb-driver-sync-4.6.1.jar:na]
        at org.springframework.data.mongodb.core.MongoTemplate.lambda$insertDocument$15(MongoTemplate.java:1552) ~[spring-data-mongodb-3.4.2.jar:3.4.2]
        at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:598) ~[spring-data-mongodb-3.4.2.jar:3.4.2]
        ... 60 common frames omitted

The failure also occurs with Spring Boot 2.7.4 when Spring Data is downgraded to the version used by Spring Boot 2.7.3:

ext['spring-data-bom.version'] = "2021.2.2"

In short, this appears to be a regression in Spring Data MongoDB which https://github.com/spring-projects/spring-data-mongodb/issues/4184 is already tracking. I'm going to close this issue in favor of it.

Comment From: ishugaliy

@wilkinsona great, thanks for the quick response to the issue.