gpt4 book ai didi

mongodb - 调用 mongo 存储库的保存方法时未调用 Mongo Date 自定义转换器

转载 作者:行者123 更新时间:2023-12-05 02:58:53 29 4
gpt4 key购买 nike

我正在使用 Linux Debian 9。我已经安装了 JDK 1.8。我使用的maven版本是3.6,springboot的版本是2.1。 mongodb版本是3.6。

下面是我试图保存在 mongodb 中的 java 类模型:

@org.springframework.data.mongodb.core.mapping.Document(collection = FileContentIndexQueue.ENTITY_COLLECTION_NAME)
@CompoundIndexes({
@CompoundIndex(name = "state_timestamp", def = "{'state' : 1, 'timestamp': -1}")
})
@QuerySupertype
public class FileContentIndexQueue extends AbstractEntityNoLock {
...

private ZonedDateTime timestamp;


public FileContentIndexQueue() {
}

public FileContentIndexQueue(String fileId, String parentId, String childType, String indexName) {
super();
this.fileId = fileId;
this.parentId = parentId;
this.childType = childType;
this.indexName = indexName;
this.state = IndexingState.TODO;
this.timestamp = ZonedDateTime.now();
}

...

public ZonedDateTime getTimestamp() {
return timestamp;
}

public void setTimestamp(ZonedDateTime timestamp) {
this.timestamp = timestamp;
}


}

我正在使用 spring data mongodb,下面是存储库类和自定义存储库类及其实现:

//Repository 
public interface FileContentIndexQueueRepositoryMongoElastic extends
MongoElasticRepository<FileContentIndexQueue, String>
, FileContentIndexQueueRepositoryCustom
{
}


//Custom Repository
public interface FileContentIndexQueueRepositoryCustom {
void addFileWithContentToExtract(AbstractEntityNoLock entity, IFile file) throws CommonAllegatiException;
void removeFileWithContentToExtract(AbstractEntityNoLock entity, IFile file) throws CommonAllegatiException;
}

//Custom Repository Class Implementation
public class FileContentIndexQueueRepositoryCustomImpl implements FileContentIndexQueueRepositoryCustom {


@Autowired
@Lazy
private FileContentIndexQueueRepositoryMongoElastic fileContentIndexQueueRepositoryMongoElastic;

@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

@Autowired
private MongoTemplate mongoTemplate;

@Override
public void addFileWithContentToExtract(AbstractEntityNoLock entity, IFile file) throws CommonAllegatiException {
if(entity.getId() == null) {
throw new CommonAllegatiException("Impossibile creare il FileContentIndexQueue da una entity senza id quindi non ancora salvata");
}
if(file == null) {
throw new CommonAllegatiException("Impossibile creare il FileContentIndexQueue da un IFile null");
}
if(file.getFileId() == null) {
throw new CommonAllegatiException("Impossibile creare il FileContentIndexQueue da un IFile senza id");
}
//da ricavare dalla entity
String parentId = entity.getId();
String indexName = elasticsearchTemplate.getPersistentEntityFor(entity.getClass()).getIndexName();
String fileId = file.getFileId();

FileContentIndexQueue fciq = new FileContentIndexQueue(fileId, parentId, CHILDTYPE, indexName);
fileContentIndexQueueRepositoryMongoElastic.save(fciq);
//**after the save is the point where the error is generated**
}

@Override
public void removeFileWithContentToExtract(AbstractEntityNoLock entity, IFile file) throws CommonAllegatiException {
...
}

}


上面的所有类都是库的一部分,我用 maven 从公司存储库下载了它,我无法修改。问题是 FileContentIndexQueue.java 模型有一个类型为 ZonedDateTime 的属性时间戳,mongo db 不支持这种类型,spring 数据没有内置转换器并抛出错误:org.bson.codecs.configuration。 CodecConfigurationException:找不到类 java.time.ZonedDateTime 的编解码器。

下面还有应用程序属性文件,其中包含我为 mongo db 和 Elasticsearch 设置的属性:

 #MongoDB
spring.data.mongodb.uri=mongodb://localhost:27017/?safe=true&w=1
spring.data.mongodb.database=operaTestDb

#Elasticsearch
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=localhost:9300
spring.data.mongoelastic.save-on-elastic=true

我尝试创建客户转换器并注册转换器以在调用 mongo 存储库的保存方法时调用。下面是我实现的解决方案的代码。

@Configuration
public class ConverterConfig {

@Autowired
MongoDbFactory mongoDbFactory;


@Bean
public MongoTemplate mongoTemplate() throws UnknownHostException {
MappingMongoConverter converter = new MappingMongoConverter(
new DefaultDbRefResolver(mongoDbFactory), new MongoMappingContext());
converter.setCustomConversions(customConversions());
converter.afterPropertiesSet();
return new MongoTemplate(mongoDbFactory, converter);
}


@Bean
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(DateToZonedDateTimeConverter.INSTANCE);
converters.add(ZonedDateTimeToDateConverter.INSTANCE);
return new MongoCustomConversions(converters);
}

enum DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {

INSTANCE;

@Override
public ZonedDateTime convert(Date source) {
return ZonedDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}

enum ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {

INSTANCE;

@Override
public Date convert(ZonedDateTime source) {
return Date.from(source.toInstant());
}
}
}


问题是即使我创建转换器并注册它们,错误:org.bson.codecs.configuration.CodecConfigurationException: 找不到类 java.time.ZonedDateTime 的编解码器。仍然存在。我在转换器中进行了调试,但它没有到达那里。就像转换器根本没有注册一样。我将不胜感激关于我应该如何调试的任何建议,或者如果您有不使用转换器的其他解决方案来解决此问题。将模型属性从 ZonedDatetime 修改为另一种日期格式不是选项,因为我无权访问该库。

亲切的问候,兰多。

最佳答案

此问题已通过在 ConverterConfig 类中进行以下修改解决:

  1. 从方法 customConversions() 中删除 bean 注释
  2. 从转换方法中删除覆盖注释
  3. 在 DateToZonedDateTimeConverter 枚举中添加 @ReadingConverter 注解
  4. 在ZonedDateTimeToDateConverterenum中添加@WritingConverter注解

以下是适用于我的 ConverterConfig 类版本。我希望它能帮助你不要像我一样浪费时间。

@Configuration
public class ConverterConfig {
@Autowired
MongoDbFactory mongoDbFactory;
@Bean
public MongoTemplate mongoTemplate() throws UnknownHostException {
MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory),
new MongoMappingContext());
converter.setCustomConversions(customConversions());
converter.afterPropertiesSet();
return new MongoTemplate(mongoDbFactory, converter);
}
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converters = new ArrayList<>();
converters.add(DateToZonedDateTimeConverter.INSTANCE);
converters.add(ZonedDateTimeToDateConverter.INSTANCE);
return new MongoCustomConversions(converters);
}
@ReadingConverter
enum DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
INSTANCE;
public ZonedDateTime convert(Date source) {
return source == null ? null : ZonedDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}
@WritingConverter
enum ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, LocalDateTime> {
INSTANCE;
public LocalDateTime convert(ZonedDateTime source) {
return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}
}

关于mongodb - 调用 mongo 存储库的保存方法时未调用 Mongo Date 自定义转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58537519/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com