4

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 をサポートしていないため)。

4

1 に答える 1