我有一个具有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
类型持久保存:
"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] 的转换器
这是完全有道理的。(它就像更新数据库中的字段一样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,但是我们使用DocumentDB 和 MongoDB API(因为 Spring Data 不支持 DocumentDB)来进行数据库操作。