Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring data MongoDb: MappingMongoConverter remove _class

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:

  1. What are the implications of moving the Person class into a different namespace?

  2. Is it possible not to pollute the object with the "_class" key; without writing a unique converter just for the Person class?

like image 397
Yuriy Nemtsov Avatar asked Jul 24 '11 23:07

Yuriy Nemtsov


2 Answers

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:

  1. You hand in a type the actual stored type can be assigned to. In that case we consider the stored type, use that for object creation. Classical example here is doing polymorphic queries. Suppose you have an abstract class Contact and your Person. You could then query for Contacts and we essentially have to determine a type to instantiate.
  2. If you - on the other hand - pass in a completely different type we'd simply marshal into that given type, not into the one stored in the document actually. That would cover your question what happens if you move the type.

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.

like image 119
Oliver Drotbohm Avatar answered Sep 30 '22 22:09

Oliver Drotbohm


Here's my annotation, and it works.

@Configuration public class AppMongoConfig {      public @Bean     MongoDbFactory mongoDbFactory() throws Exception {         return new SimpleMongoDbFactory(new Mongo(), "databasename");     }      public @Bean     MongoTemplate mongoTemplate() throws Exception {          //remove _class         MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext());         converter.setTypeMapper(new DefaultMongoTypeMapper(null));          MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);          return mongoTemplate;      }  } 
like image 29
mkyong Avatar answered Sep 30 '22 22:09

mkyong