В настоящее время я использую данные весны mongodb, а файл конфигурации расширяется. AbstractMongoConfiguration:
@Configuration
@EnableMongoRepositories(basePackages = "com.mycompany")
@EnableMongoAuditing
public class MongoConfig extends AbstractMongoConfiguration
{
Я переопределяю метод getMappingBasePackage()
, чтобы настроить пакет на сканирование следующим образом:
@Override
protected String getMappingBasePackage()
{
return "com.mycompany";
}
Я отлаживал код и заметил несколько интересных вещей:
- Есть два места, где я получаю
java.lang.InstantiationError
.Оба случая происходят, когда я пытаюсь прочитать документ из монго, в котором есть ссылка на абстрактный класс (ParentClass).Он пытается создать экземпляр абстрактного класса вместо того, чтобы найти аннотацию @TypeAlias
, которую я добавил к дочерним классам.
Вот как выглядит мой ParentClass:
@Document
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.EXISTING_PROPERTY, visible=true, property="type")
@JsonSubTypes({
@Type(value=Child1.class, name="JSON_TYPE_CHILD1"),
@Type(value=Child2.class, name="JSON_TYPE_CHILD2"),
@Type(value=Child3.class, name="JSON_TYPE_CHILD3")
})
public abstract class ParentClass
{
...
Мои дочерние классы выглядят так:
@Document
@JsonTypeName("JSON_TYPE_CHILD1")
@TypeAlias("ALIAS_TYPE_CHILD1")
public class Child1 extends ParentClass
{
...
Вот как выглядит (упрощенно) json, в котором я пытаюсь прочитать:
{
"_id" : ObjectId("5c86d31388f13344f4098c64"),
"listOfWrapperClass" : [
{
"parentClass" : {
"type" : "JSON_TYPE_CHILD1",
"prop1" : 50.0,
"prop2" : 50.0,
"_class" : "ALIAS_TYPE_CHILD1"
},
"isReportOutOfDate" : false,
}
],
"_class" : "com.mycompany.domain.job.Job"
}
Когда я отлаживаю данные пружиныпроблема возникает в DefaultTypeMapper:
private TypeInformation<?> getFromCacheOrCreate(Alias alias) {
Optional<TypeInformation<?>> typeInformation = typeCache.get(alias);
if (typeInformation == null) {
typeInformation = typeCache.computeIfAbsent(alias, getAlias);
}
return typeInformation.orElse(null);
}
Он отлично загружает класс-оболочку, но когда он попадает в дочерний класс, псевдоним устанавливается в «ALIAS_TYPE_CHILD1», как и должно быть, но в typeCache следующие значения:
{
NONE=Optional.empty,
ALIAS_TYPE_CHILD1=Optional.empty,
com.mycompany.domain.job.Job=Optional[com.mycompany.domain.job.Job]
}
Поскольку ключ "ALIAS_TYPE_CHILD1" имеет в качестве значения Optional.empty, код не получает правильный целевой тип для загрузки и поэтому использует rawType, который является ParentClass.Который взрывается, потому что не может создать экземпляр абстрактного класса.Вот трассировка стека:
Caused by: java.lang.InstantiationError: com.mycompany.domain.job.base.ParentClass
at com.mycompany.domain.job.base.ParentClass_Instantiator_q3kytg.newInstance(Unknown Source)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:226)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:84)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:272)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:245)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1491)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1389)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:378)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:295)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:275)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:245)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readCollectionOrArray(MappingMongoConverter.java:1038)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readValue(MappingMongoConverter.java:1489)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1389)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:378)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.populateProperties(MappingMongoConverter.java:295)
at ...
Странная вещь, если я вставляю новый документ с @TypeAlias("ALIAS_TYPE_CHILD1")
first , упомянутый выше typeCache
заполняется правильно так:
{
NONE=Optional.empty,
ALIAS_TYPE_CHILD1=Optional[com.mycompany.domain.job.base.Child1],
com.mycompany.domain.job.Job=Optional[com.mycompany.domain.job.Job]
}
Когда я обнаруживаю OneOne сразу после вставки, я могу читать в документе без ошибок, поскольку он использует Child1 для создания экземпляра pojo вместо ParentClass.Если я пытаюсь читать сначала, тогда не имеет значения, вставлю ли я после этого или нет, потому что typeCace
вводит туда неверное значение и использует его до тех пор, пока вы не перезапустите сервер.
Я думаю, что естьбыло изменение в конфигурации или в настройках по умолчанию.Мне удалось решить все другие проблемы с обновлением, но этот сбил меня с толку.Я был бы шокирован, если в весенних данных есть реальная проблема, потому что я уверен, что кто-то уже столкнулся с этой проблемой, потому что я не могу быть единственным, кто пытается использовать @TypeAlias
с spring-data-mongodb.Не говоря уже о том, что все прекрасно работает с предыдущей версией загрузочной пружины, которую я использовал (1.4.5, которая использует spring-data-mongodb 1.9.8.RELEASE).
Любые мысли или советы о том, что попробовать дальше, приветствуются.Я просто не знаю, что делать дальше.