Solución:
Así que aquí está la historia: agregamos el tipo de forma predeterminada como una especie de pista de qué clase instanciar en realidad. Como tiene que canalizar un tipo para leer el documento a través de MongoTemplate
de todos modos hay dos opciones posibles:
- Usted entrega un tipo al que se le puede asignar el tipo almacenado real. En ese caso, consideramos el tipo almacenado, utilícelo para la creación de objetos. El ejemplo clásico aquí es hacer consultas polimórficas. Suponga que tiene una clase abstracta
Contact
y tuPerson
. A continuación, puede consultarContact
s y nosotros esencialmente tengo que determinar un tipo para instanciar. - Si, por otro lado, pasa un tipo completamente diferente, simplemente clasificaríamos en ese tipo dado, no en el almacenado en el documento en realidad. Eso cubriría su pregunta sobre qué sucede si mueve el tipo.
Es posible que le interese ver este boleto que cubre algún tipo de estrategia de mapeo de tipo conectable para convertir la información de tipo en un tipo real. Esto puede servir simplemente para ahorrar espacio, ya que es posible que desee reducir un nombre de clase calificado largo a un hash de unas pocas letras. También permitiría escenarios de migración más complejos en los que podría encontrar claves de tipo completamente arbitrarias producidas por otro cliente de almacén de datos y vincularlas a tipos de Java.
Aquí está mi anotación y funciona.
@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;
}
}
Si quieres deshabilitar _class
atributo por defecto, pero conserva el polimorfismo para clases especificadas, puede definir explícitamente el tipo de _class
(opcional) campo configurando:
@Bean
public MongoTemplate mongoTemplate() throws Exception {
Map<Class<?>, String> typeMapperMap = new HashMap<>();
typeMapperMap.put(com.acme.domain.SomeDocument.class, "role");
TypeInformationMapper typeMapper1 = new ConfigurableTypeInformationMapper(typeMapperMap);
MongoTypeMapper typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, Arrays.asList(typeMapper1));
MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext());
converter.setTypeMapper(typeMapper);
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
return mongoTemplate;
}
Esto preservará _class
campo (o lo que quieras nombrar en construtor) solo para entidades especificadas.
También puede escribir el propio TypeInformationMapper
por ejemplo, basado en anotaciones. Si anota su documento con @DocumentType("aliasName")
mantendrá el polimorfismo manteniendo el alias de clase.
Lo he explicado brevemente en mi blog, pero aquí hay un fragmento de código rápido: https://gist.github.com/athlan/6497c74cc515131e1336