Spring Data MongoDB игнорирует информацию _class
-
20-12-2019 - |
Вопрос
У меня возникли проблемы с использованием Spring-data-mongodb 1.3.3.RELEASE и Java 1.6.
Моя настройка немного сложна, поскольку мне приходится иметь дело с устаревшими данными, поэтому у меня есть собственный TypeMapper
(расширение DefaultMongoTypeMapper
) и две разные комбинации преобразователей чтения/записи.Дополнительно я использую @TypeAlias
для установки _class
информация в базе данных.
Проблемные модели состоят из нескольких вложенных списков, некоторые из них имеют вид
List<DocumentValue>
MyObject может содержать список объектов
List<Object>
который может содержать другой DocumentValue
объект.
Кажется, эта настройка работает, модульные тесты выполняются без проблем, отображение объектов в отладчике выглядит довольно хорошо.Мое приложение является веб-приложением, и я могу писать DocumentValue
в коллекцию, _class
информация присутствует.
Пока я не выключаю сервер (в моем случае кот), сопоставление объектов работает.Но когда я перезапускаю сервер (запускаю новую JVM), DocumentValue
объекты отображаются неправильно, но рассматриваются как java.util.Map
.А _class
информация, похоже, игнорируется.Я предполагаю, что может быть проблема с моим контекстом сопоставления (должны ли быть зарегистрированы объекты моей модели во время запуска контекста Spring?), но я не могу найти неправильную конфигурацию.Были ли у кого-нибудь подобные проблемы или есть предложения?
Решение
Спасибо за ваш ответ.Кажется, я нашел причину, по которой _class был проигнорирован.Вы правы, я использую необычную комбинацию TypeMapper.
Позвольте мне показать вам мой CustomTypeMapper:
public class CustomTypeMapper extends DefaultMongoTypeMapper {
public CustomTypeMapper (MongoMappingContext mappingContext) {
super(DEFAULT_TYPE_KEY,
Arrays.asList(new MappingContextTypeInformationMapper(
mappingContext)));
}
@Override
public <T> TypeInformation<? extends T> readType(DBObject source,
TypeInformation<T> basicType) {
// do some custom recognition
// or just to the common type mapping
return super.readType(source, basicType);
}
}
Помимо общего распознавания типов, особой особенностью является конструктор, в котором MappingContextTypeInformationMapper используется для использования аннотаций @TypeAlias.
Ключевым моментом здесь является MongoMappongContext, который необходим.В нефункциональном случае я инициализировал CustomTypeMapper следующим образом:
<bean id="customTypeMapper" class="de.flexguse.repository.CustomTypeMapper">
<constructor-arg name="mappingContext">
<bean class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
</constructor-arg>
</bean>
это сработало, но было неправильно, поскольку новый экземпляр MongoMappingContext не содержал никакой информации о типе, предоставленной путем установки атрибута базового пакета в
<mongo:mapping-converter id="customMappingConverter" db-factory-ref="mongoDbFactory"
type-mapper-ref="customTypeMapper" base-package="de.flexguse.model" >
<mongo:custom-converters>
... some custom converters ...
</mongo:custom-converters>
</mongo:mapping-converter>
К сожалению, мне не удалось выяснить, где создается MongoMappingContext, чтобы иметь возможность использовать его в качестве аргумента конструктора, поэтому я изобрел простой компонент MongoMappingContextProvider, который получает MongoMappingContext с помощью @Autowire.
public class MongoMappingContextProvider {
@Autowired
private MongoMappingContext mappingContext;
/**
* @return the mappingContext
*/
public MongoMappingContext getMappingContext() {
return mappingContext;
}
}
Конфигурация Spring CustomTypeMapper теперь выглядит так
<bean id="mongoMappingContextProvider" class="de.flexguse.repository.MongoMappingContextProvider" />
<bean id="customTypeMapper" class="de.flexguse.repository.CustomTypeMapper">
<constructor-arg name="mappingContext" value="#{mongoMappingContextProvider.mappingContext}" />
</bean>
Это решение работает для меня.
Кстати, чтобы иметь всю информацию о типах для всех используемых мной bean-компонентов модели, я добавил @Document к каждому сохраняемому bean-компоненту модели - на всякий случай;)
Возможно, это поможет кому-то еще с похожими проблемами.
С уважением, Кристоф
Другие советы
Я подозреваю, что проблема возникла из-за необычной комбинации TypeMapper
использование и конвертеры. Если реализованный вручную Converter
экземпляр для определенного типа зарегистрирован, что Converter
отвечает за создание объекта, сохраняемого и читаемого MongoDB и из него.Это означает, что вашему экземпляру преобразователя необходимо самому записывать информацию о типе.
Если вы не можете заставить его работать и можете скомпилировать небольшой пример проекта, чтобы воспроизвести проблему (предпочтительно тестовый пример для выполнения), не стесняйтесь подать заявку в нашем ДЖИРА пример.