The default MappingMongoConverter adds a custom type key ("_class") to each object in the database. So, if I create a Person:
package my.dto;
public class Person {
String name;
public Person(String name) {
this.name = name;
}
}
and save it to the db:
MongoOperations ops = new MongoTemplate(new Mongo(), "users");
ops.insert(new Person("Joe"));
the resulting object in the mongo will be:
{ "_id" : ObjectId("4e2ca049744e664eba9d1e11"), "_class" : "my.dto.Person", "name" : "Joe" }
Questions:
What are the implications of moving the Person class into a different namespace?
Is it possible not to pollute the object with the "_class" key; without writing a unique converter just for the Person class?
This is my one line solution:
I struggled a long time with this problem. I followed the approach from mkyong but when I introduced a
LocalDate
attribute (any JSR310 class from Java 8) I received the following exception:The corresponding converter
org.springframework.format.datetime.standard.DateTimeConverters
is part of Spring 4.1 and is referenced in Spring Data MongoDB 1.7. Even if I used newer versions the converter didn't jump in.The solution was to use the existing
MappingMongoConverter
and only provide a newDefaultMongoTypeMapper
(the code from mkyong is under comment):To summarize:
AbstractMongoConfiguration
EnableMongoRepositories
mongoTemplate
get converter from base class, this ensures that the type conversion classes are registeredHere's my annotation, and it works.
you just need to add the @TypeAlias annotation to the class defintion over changing the type mapper
So here's the story: we add the type by default as some kind of hint what class to instantiate actually. As you have to pipe in a type to read the document into via
MongoTemplate
anyway there are two possible options:Contact
and yourPerson
. You could then query forContact
s and we essentially have to determine a type to instantiate.You might be interested in watching this ticket which covers some kind of pluggable type mapping strategy to turn the type information into an actual type. This can serve simply space saving purposes as you might want to reduce a long qualified class name to a hash of a few letters. It would also allow more complex migration scenarios where you might find completely arbitrary type keys produced by another datastore client and bind those to Java types.