我有一个具有df$chr1
类型成员变量的Java类:
Instant
我使用MongoTemplate更新数据库中的public class SomeRecord {
private String someId;
private Instant someInstant;
// getters and setters
}
字段:
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")
在这种情况下,我得到一个例外:
org.springframework.core.convert.ConverterNotFoundException:没有 转换器发现能够从类型[java.lang.String]转换为 输入[java.time.Instant]
这完全有道理。 (它会将数据库中的字段更新为updateSomeRecordBySomeId("SOME-ID", "2017-07-11T07:26:44.269Z");
。String
)
<小时/> 所以我添加了一个转换器如下:
MongoConfig.java:
"someInstant" : "2017-07-11T07:26:44.269Z"
StringToInstantConverter.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);
}
}
添加上述转换后,我不再获得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
检查都不适用于实际方案。那么关注的重点是转换没有发生的原因?
我们的实际数据存储是DocumentDB,但我们使用DocumentDB with MongoDB API(因为Spring Data不支持DocumentDB)来进行数据库操作。
答案 0 :(得分:2)
您的更新逻辑以类型不可知的方式编写:您可以传递任何对象类型(整数,长整数,布尔值,字符串,日期等),并通过使用新值和新类型。注意:像MongoDB这样的面向文档的数据库没有固定的模式,因此存储的数据可以随意更改数据类型。
您在使用ConverterNotFoundException
引入转换器之前遇到的问题不是在更新操作期间,而是在检索更新的对象并将其设置为Java bean模型期间:Java类定义someInstant
属性为Instant
/ Date
类型,但数据库提供了String
值。
介绍转换器后,解决了阅读问题,但仅适用于String
和Date
类型。如果使用某个someInstant
值更新boolean
属性,您将回到该问题以读取该对象并将其映射到Java bean。