[英]How to save Java 8 Instant to MongoDB as Date type using Spring MongoTemplate?
I have a Java class having an Instant
type of member variable: 我有一个具有
Instant
类型成员变量的Java类:
public class SomeRecord {
private String someId;
private Instant someInstant;
// getters and setters
}
I am using MongoTemplate to update the someInstant
field in database: 我使用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);
}
This works great if I am calling the method as: 如果我将方法调用为:
updateSomeRecordBySomeId("SOME-ID", Instant.now());
persisting the field in DB as a Date
type: "someInstant" : ISODate("2017-07-11T07:26:44.269Z")
将数据库中的字段保存为
Date
类型: "someInstant" : ISODate("2017-07-11T07:26:44.269Z")
Now the method may also be called as: updateSomeRecordBySomeId("SOME-ID", "2017-07-11T07:26:44.269Z");
现在该方法也可以被称为:
updateSomeRecordBySomeId("SOME-ID", "2017-07-11T07:26:44.269Z");
In this case I get an exception as: 在这种情况下,我得到一个例外:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.time.Instant]
org.springframework.core.convert.ConverterNotFoundException:找不到能够从类型[java.lang.String]转换为类型[java.time.Instant]的转换器
which makes complete sense. 这完全有道理。 (It updates the field in the DB as
String
though. "someInstant" : "2017-07-11T07:26:44.269Z"
) (它将DB中的字段更新为
String
。 "someInstant" : "2017-07-11T07:26:44.269Z"
)
MongoConfig.java: MongoConfig.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);
}
}
StringToInstantConverter.java: 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); } }
After adding the above converter I am not getting ConverterNotFoundException
any longer, but the field someInstant
is being persisted as plain string: "someInstant" : "2017-07-11T07:26:44.269Z"
添加上面的转换器后,我不再获得
ConverterNotFoundException
,但字段someInstant
被保存为普通字符串: "someInstant" : "2017-07-11T07:26:44.269Z"
And that's what my question is. 这就是我的问题所在。 I know that the converter is being identified that is the reason I am not getting the exception anymore.
我知道正在识别转换器,这就是我不再获得异常的原因。 But why the converter is not converting the
String
to Instant
? 但是为什么转换器没有将
String
转换为Instant
? Why the field is being persisted as plain String
? 为什么字段被保持为普通
String
? Is the converter supplied incorrect? 转换器供应不正确吗? How to write converter for this case?
如何为这种情况编写转换器?
Note: 注意:
I have simplified the code to focus on the actual problem. 我简化了代码以专注于实际问题。 In actual the method does not receive the
someInstant
field as parameter. 实际上,该方法不接收
someInstant
字段作为参数。 So writing overloaded method is not going to be applicable here. 因此,编写重载方法不适用于此。 Also any kind of
instanceOf
check inside the method won't work for the actual scenario. 此外,方法内的任何类型的
instanceOf
检查都不适用于实际场景。 So the focus is on the question why the conversion not happening? 所以关注的重点是为什么转换没有发生?
The actual data-store for us is DocumentDB, but we use DocumentDB with MongoDB API (as Spring Data does not support DocumentDB) for our database operations. 我们的实际数据存储是DocumentDB,但我们使用DocumentDB和MongoDB API (因为Spring Data不支持DocumentDB)来进行数据库操作。
Your update logic is written in type agnostic way: you can pass any object type (Integer, Long, Boolean, String, Date, etc.) and it will be persisted in DB by overriding the existing value/type with new value and new type . 您的更新逻辑以类型不可知的方式编写:您可以传递任何对象类型(整数,长整数,布尔值,字符串,日期等),并通过使用新值和新类型覆盖现有值/类型将其保留在DB中。 Note: document oriented databased like MongoDB have no fixed schema, so stored data can arbitrary change data types.
注意:面向文档的数据库像MongoDB一样没有固定的模式,因此存储的数据可以随意更改数据类型。
The issue you had before you introduced converter with ConverterNotFoundException
was not during update action, but during retrieval of updated object and setting it into your Java bean model: Java class defined someInstant
property to be of an Instant
/ Date
type, but database supplied a String
value. 您在使用
ConverterNotFoundException
引入转换ConverterNotFoundException
之前遇到的问题不是在更新操作期间,而是在检索更新的对象并将其设置为Java bean模型期间:Java类将someInstant
属性定义为Instant
/ Date
类型,但数据库提供了String
值。
After you introduced a converter the issue of reading was solved, but only for String
and Date
types. 介绍转换器后,解决了读取问题,但仅限于
String
和Date
类型。 If you update the someInstant
property with some boolean
value, you'll get back to the issue to read the object and map it to you Java bean. 如果使用某个
boolean
值更新someInstant
属性,则会回到该问题以读取对象并将其映射到Java bean。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.