デフォルトMappingMongoConverterは、データベース内の各オブジェクトにカスタムタイプキー( "_class")を追加します。したがって、Personを作成すると、次のようになります。
package my.dto;
public class Person {
String name;
public Person(String name) {
this.name = name;
}
}
それをdbに保存します。
MongoOperations ops = new MongoTemplate(new Mongo(), "users");
ops.insert(new Person("Joe"));
mongoの結果のオブジェクトは次のようになります。
{ "_id" : ObjectId("4e2ca049744e664eba9d1e11"), "_class" : "my.dto.Person", "name" : "Joe" }
質問:
Personクラスを別の名前空間に移動するとどのような影響がありますか?
「_class」キーでオブジェクトを汚染しないことは可能ですか? Personクラス専用の独自のコンバーターを作成せずに?
だからここに話があります:デフォルトで型を何らかのクラスのヒントとして実際にインスタンス化するクラスを追加します。パイプを使用してドキュメントをMongoTemplate
に読み込むために型をパイプする必要があるので、とにかく2つの可能なオプションがあります。
Contact
とPerson
があるとします。次に、Contact
sをクエリすると、インスタンス化するタイプを本質的に決定する必要があります。タイプ情報を実際のタイプに変換するプラグイン可能なタイプマッピング戦略をカバーする this ticket の監視に興味があるかもしれません。長い修飾クラス名を数文字のハッシュにしたい場合があるので、これは単にスペース節約の目的に役立ちます。また、別のデータストアクライアントによって生成された完全に任意のタイプキーを見つけ、それらをJavaタイプにバインドすることもある。
これが私の注釈です。うまくいきます。
@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;
}
}
<mongo:mongo Host="hostname" port="27017">
<mongo:options
...options...
</mongo:mongo>
<mongo:db-factory dbname="databasename" username="user" password="pass" mongo-ref="mongo"/>
<bean id="mongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
<constructor-arg name="typeKey"><null/></constructor-arg>
</bean>
<bean id="mongoMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
<bean id="mongoConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg name="mappingContext" ref="mongoMappingContext" />
<property name="typeMapper" ref="mongoTypeMapper"></property>
</bean>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
<constructor-arg name="mongoConverter" ref="mongoConverter" />
<property name="writeResultChecking" value="EXCEPTION" />
</bean>
__class
_属性をデフォルトで無効にしたいが、指定されたクラスのポリモーフィズムを維持したい場合は、次のように構成することにより、明示的に__class
_(オプション)フィールドのタイプを定義できます。
_@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;
}
_
これにより、指定されたエンティティのみの__class
_フィールド(またはコンストラクタで名前を付けたいもの)が保持されます。
たとえば注釈に基づいて、独自のTypeInformationMapper
を記述することもできます。 @DocumentType("aliasName")
でドキュメントに注釈を付けると、クラスのエイリアスを保持することでポリモーフィズムを維持できます。
ブログで簡単に説明しました ですが、簡単なコードの一部を次に示します: https://Gist.github.com/athlan/6497c74cc515131e1336
Mkyongの答えはまだ機能しますが、いくつかのビットが廃止されており、クリーンアップの危機に瀕している可能性があるため、私のバージョンのソリューションを追加したいと思います。
例:MappingMongoConverter(mongoDbFactory(), new MongoMappingContext())
はnew MappingMongoConverter(dbRefResolver, new MongoMappingContext());
を優先して非推奨になり、SimpleMongoDbFactory(new Mongo(), "databasename");
はnew SimpleMongoDbFactory(new MongoClient(), database);
を優先します。
だから、非推奨の警告なしの私の最終的な作業の答えは:
@Configuration
public class SpringMongoConfig {
@Value("${spring.data.mongodb.database}")
private String database;
@Autowired
private MongoDbFactory mongoDbFactory;
public @Bean MongoDbFactory mongoDBFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(), database);
}
public @Bean MongoTemplate mongoTemplate() throws Exception {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
// Remove _class
MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
return new MongoTemplate(mongoDBFactory(), converter);
}
}
これが非推奨の警告なしでクリーンなクラスを望んでいる人々を助けることを願っています。
これは私の1行のソリューションです。
@Bean
public MongoTemplate mongoTemplateFraud() throws UnknownHostException {
MongoTemplate mongoTemplate = new MongoTemplate(getMongoClient(), dbName);
((MappingMongoConverter)mongoTemplate.getConverter()).setTypeMapper(new DefaultMongoTypeMapper(null));//removes _class
return mongoTemplate;
}
私はこの問題に長い間苦しんでいました。私は mkyong からのアプローチに従いましたが、LocalDate
属性(Java 8からのJSR310クラス))を導入すると、次の例外が発生しました:
org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type [Java.time.LocalDate] to type [Java.util.Date]
対応するコンバータorg.springframework.format.datetime.standard.DateTimeConverters
はSpring 4.1の一部であり、Spring Data MongoDB 1.7で参照されています。新しいバージョンを使用しても、コンバーターはジャンプしませんでした。
解決策は、既存のMappingMongoConverter
を使用し、新しいDefaultMongoTypeMapper
のみを提供することでした(mkyongからのコードはコメントの下にあります):
@Configuration
@EnableMongoRepositories
class BatchInfrastructureConfig extends AbstractMongoConfiguration
{
@Override
protected String getDatabaseName() {
return "yourdb"
}
@Override
Mongo mongo() throws Exception {
new Mongo()
}
@Bean MongoTemplate mongoTemplate()
{
// overwrite type mapper to get rid of the _class column
// get the converter from the base class instead of creating it
// def converter = new MappingMongoConverter(mongoDbFactory(), new MongoMappingContext())
def converter = mappingMongoConverter()
converter.typeMapper = new DefaultMongoTypeMapper(null)
// create & return template
new MongoTemplate(mongoDbFactory(), converter)
}
要約する:
AbstractMongoConfiguration
EnableMongoRepositories
で注釈を付けるmongoTemplate
で、ベースクラスからコンバーターを取得します。これにより、型変換クラスが登録されます。@Configuration
public class MongoConfig {
@Value("${spring.data.mongodb.database}")
private String database;
@Value("${spring.data.mongodb.Host}")
private String Host;
public @Bean MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(Host), database);
}
public @Bean MongoTemplate mongoTemplate() throws Exception {
MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory()),
new MongoMappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
return mongoTemplate;
}
}
タイプマッパーを変更するだけで、@ TypeAliasアノテーションをクラス定義に追加する必要があります。