英文:
Java Spring how to persist a date field in MongoDb as long
问题
我正在工作的项目中有一个集合,其中一个字段是表示日期的long值。
相应的Java类模型具有作为long字段对应的Date字段。
我们使用Json Schema创建集合并设置数据格式和所需字段。
数据库中的数据是使用json文件导入的,并且可以通过我们的Java应用程序进行读取,没有任何问题:驱动程序能够将long信息转换为Date,在模型类上没有任何注释或其他内容。
当我们需要从Java应用程序中保存这个同样的文档时,问题出现了。似乎驱动程序无法进行反向转换,从Date转换为long。
你有任何建议吗?
英文:
The project I'm working on has a collection where one of its fields is a long representing a date.
The representing Java class model has a Date field as a correspondence of the long one.
We used a Json Schema to create the collection and set the data format and required fields.
The data on the db has been imported using a json file and can be read through our Java application without problems: the driver is able to cast the long information in a Date, with no annotations or other stuff on the model class.
The problem came out when we needed to save this same document from the java application. It seems that the driver is not able to do the reverse cast, from Date to long.
Do you have any suggestion?
答案1
得分: 0
我将日期更改为Instant,但并没有解决保存问题,而在读取时却引发了以下异常:
> "org.springframework.core.convert.ConverterNotFoundException: 找不到可从类型[java.lang.Long]转换为类型[java.time.Instant]的转换器"
为了解决这个问题,我需要创建一个转换器:
public class FromLongToInstantConverter implements Converter<Long, Instant> {
@Override
public Instant convert(Long source) {
return Instant.ofEpochMilli(source);
}
}
这个转换器需要被Mongo驱动加载,所以我不得不创建这个类:
public abstract class AbstractMongoConfiguration extends AbstractMongoClientConfiguration {
@Bean
@Override
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new FromLongToInstantConverter());
return new MongoCustomConversions(converters);
}
/**
*
* @return
*/
@Bean
@Override
public MongoTemplate mongoTemplate() {
MappingMongoConverter converter = new MappingMongoConverter(
new DefaultDbRefResolver(mongoDbFactory()), new MongoMappingContext());
converter.setCustomConversions(customConversions());
converter.afterPropertiesSet();
return new MongoTemplate(mongoDbFactory(), converter);
}
}
这个类将会在应用程序中由MongoConfig.java扩展使用。
然而,这个解决方案会导致这个Bug:https://stackoverflow.com/questions/52512580/spring-boot-illegal-reflective-access-by-org-springframework-cglib-core-reflec
我为保存操作做了类似的转换器,并将其添加到上述的AbstractMongoConfiguration中:
public class FromInstantToLongConverter implements Converter<Instant, Long> {
@Override
public Long convert(Instant source) {
return source.toEpochMilli();
}
}
英文:
I changed the Date to Instant and it didn't solved the saving problem, but on read it gives the following exception:
> "org.springframework.core.convert.ConverterNotFoundException: No
> converter found capable of converting from type [java.lang.Long] to
> type [java.time.Instant]"
To solve this I needed to create a converter:
public class FromLongToInstantConverter implements Converter<Long, Instant> {
@Override
public Instant convert(Long source) {
return Instant.ofEpochMilli(source);
}
}
This converter needed to be loaded by Mongo drivers so I had to create this class:
public abstract class AbstractMongoConfiguration extends AbstractMongoClientConfiguration {
@Bean
@Override
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(new FromLongToInstantConverter());
return new MongoCustomConversions(converters);
}
/**
*
* @return
*/
@Bean
@Override
public MongoTemplate mongoTemplate() {
MappingMongoConverter converter = new MappingMongoConverter(
new DefaultDbRefResolver(mongoDbFactory()), new MongoMappingContext());
converter.setCustomConversions(customConversions());
converter.afterPropertiesSet();
return new MongoTemplate(mongoDbFactory(), converter);
}
}
Which will be extended by the MongoConfig.java within the application.
This solution however leads to this bug: https://stackoverflow.com/questions/52512580/spring-boot-illegal-reflective-access-by-org-springframework-cglib-core-reflec
I did a similar converter for the saving operation and added it to the above AbstractMongoConfiguration:
public class FromInstantToLongConverter implements Converter<Instant, Long> {
@Override
public Long convert(Instant source) {
return source.toEpochMilli();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论