Instant
メンバー変数の型を持つ Java クラスがあります。
public class SomeRecord {
private String someId;
private Instant someInstant;
// getters and setters
}
MongoTemplate を使用しsomeInstant
てデータベースのフィールドを更新しています。
public SomeRecord updateSomeRecordBySomeId(final String someId, Object someInstant) {
Query query = new Query();
query.addCriteria(Criteria.where("someId").is(someId));
Update update = new Update();
update.set("someInstant", someInstant);
return operations.findAndModify(query, update, new FindAndModifyOptions().returnNew(true), SomeRecord.class);
}
メソッドを次のように呼び出している場合、これはうまく機能します。
updateSomeRecordBySomeId("SOME-ID", Instant.now());
Date
フィールドをタイプ
として DB に永続化します。"someInstant" : ISODate("2017-07-11T07:26:44.269Z")
現在、メソッドは次のように呼び出すこともできます。
updateSomeRecordBySomeId("SOME-ID", "2017-07-11T07:26:44.269Z");
この場合、次のような例外が発生します。
org.springframework.core.convert.ConverterNotFoundException: タイプ [java.lang.String] からタイプ [java.time.Instant] に変換できるコンバーターが見つかりませんでした
これは完全に理にかなっています。(あたかもDBのフィールドを更新しString
ます。"someInstant" : "2017-07-11T07:26:44.269Z"
)
そこで、次のようにコンバーターを追加しました。
MongoConfig.java:
@Configuration
@ComponentScan(basePackages = {"dao package path here"})
public class MongoConfig {
@Autowired
private MongoDbFactory mongoDbFactory;
@Bean
public MongoTemplate mongoTemplate() {
MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory),
new MongoMappingContext());
converter.setCustomConversions(new CustomConversions(Collections.singletonList(new StringToInstantConverter())));
return new MongoTemplate(mongoDbFactory, converter);
}
}
StringToInstantConverter.java:
public class StringToInstantConverter implements Converter<String, Instant> {
@Override
public Instant convert(String utcString) {
// TODO: Make it generic for any time-zone
return Instant.parse(utcString);
}
}
上記のコンバーターを追加した後、私はもう取得していConverterNotFoundException
ませんが、フィールドsomeInstant
はプレーン文字列として永続化されています:"someInstant" : "2017-07-11T07:26:44.269Z"
それが私の質問です。コンバーターが識別されていることがわかっているため、例外が発生しなくなりました。しかし、コンバーターが を に変換しないのはなぜString
ですかInstant
? フィールドがプレーンとして永続化されているのはなぜString
ですか? 付属のコンバーターが間違っていませんか?この場合のコンバーターの書き方は?
ノート:
実際の問題に焦点を当てるためにコードを単純化しました。
someInstant
実際には、メソッドはフィールドをパラメーターとして受け取りません。したがって、オーバーロードされたメソッドを記述することは、ここでは適用できません。また、メソッド内のあらゆる種類のinstanceOf
チェックは、実際のシナリオでは機能しません。では、なぜコンバージョンが起こらないのかという疑問に焦点が当てられています。実際のデータ ストアは DocumentDB ですが、データベース操作にはMongoDB API で DocumentDBを使用します(Spring Data は DocumentDB をサポートしていないため)。