Я работаю с Linux Debian 9. Я установил JDK 1.8. Я использую Maven версии 3.6, а версия Springboot - 2.1. Версия mongodb - 3.6.
Ниже приведена модель класса в Java, которую я пытаюсь сохранить в mongodb:
@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;
}
}
Я использую данные весны 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 не поддерживает этот тип, а данные пружины не имеют встроенного преобразователя и выдают ошибку: org.bson.codecs.configuration. CodecConfigurationException: Невозможно найти кодек для класса java.time.ZonedDateTime.
Также под ним находится файл свойств приложения со свойствами, которые я установил для mongo db и эластичного поиска:
#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 в другой формат даты не допускается, поскольку у меня нет доступа к этой библиотеке.
С уважением, Рандо.