spring-data-mongodb icon indicating copy to clipboard operation
spring-data-mongodb copied to clipboard

@MongoId has no effect

Open maxim04 opened this issue 3 years ago • 4 comments

Using spring-boot-starter-data-mongodb:2.6.6

  • spring-boot-starter:2.6.6
  • mongodb-driver-sync:4.4.2
  • spring-data-mongodb: 3.3.3

Documentation https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo-template.id-handling states that the @MongoId annotation can be used to control the data that gets written to mongodb. I want to write the auto generated _id field to the database as a string, but no matter the annotations I use it always get's written as an ObjectId. Here is the code:

@SpringBootApplication
@EnableMongoRepositories
public class Demo1Application implements CommandLineRunner {
    @Autowired
    UserRepository userRepository;

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

    @Override
    public void run(String... args) throws Exception {
        userRepository.deleteAll();

        userRepository.save(new User());
    }
}

@Document
class User {
    @MongoId
    String id;
}

interface UserRepository extends MongoRepository<User, String> {
}

And this is the data produced in the database:

{  "_id": {    "$oid": "625da3621aab8475434b3b66"  },  "_class": "com.example.demo.User"}

Even if I try @MongoId(targetType = FieldType.STRING) the _id field type in the database is still ObjectId. If I use spring's @Id annotation, the _id field gets written as an ObjectId which is no different to what @MongoId produces. Is this a bug or am I misunderstanding the use of @MongoId? Thanks

maxim04 avatar Apr 18 '22 17:04 maxim04

Spring Data doesn't write any _id into the database (in your case) hence the driver itself generates the identifier value, see:

https://github.com/mongodb/mongo-java-driver/blob/master/bson/src/main/org/bson/codecs/BsonDocumentCodec.java#L149-L152

@MongoId has only an effect if you provide the identifier value. Also, there's no way to tell the document codec to use a string representation of the identifier as these things are outside of our control.

mp911de avatar Apr 21 '22 11:04 mp911de

I see, this question arose as a result of repo lookups by DocumentReference id's returning empty results, for which I'll raise a separate issue. Thanks

maxim04 avatar Apr 21 '22 20:04 maxim04

I wonder whether we could simply generate identifiers within Spring Data Mongo as the Id generation isn't tied to the server. Our mapping metadata has sufficient details and we could generate identifiers as String, BigDecimal, and byte[]. Let me take the ticket to our team to see whether we can do something about it.

mp911de avatar Apr 22 '22 11:04 mp911de

FWIW I noticed that when using @MongoId(targetType = FieldType.STRING) in entity "A" and having a DocumentReference to this entity in entity "B", the document reference field for entity "B" is written to the db as a String type, but entity "A" still gets an id of type ObjectId.

maxim04 avatar Apr 25 '22 17:04 maxim04