Не удалось найти PersistentEntity для класса типов при использовании @EnableMongoAuditing - PullRequest
5 голосов
/ 30 апреля 2019

Я получаю сообщение об ошибке " Не удалось найти PersistentEntity для класса " при использовании функций @EnableMongoAuditing вместе с MongoRepository.Это происходит, когда я сохраняю документ, когда коллекция еще не присутствует в базе данных.

Я пробовал все, что упомянуто в:

, но ничего не работает.

Упомянутые вещи:

Расширение MongoConfigby AbstractMongoConfiguration и переопределите все методы.

Вот мой код, который воспроизвел ту же ошибку:

MongoConfig class

@Configuration
public class MongoConfig extends AbstractMongoConfiguration {

    @Value("${spring.data.mongodb.host}")
    private String mongoHost;

    @Value("${spring.data.mongodb.port}")
    private String mongoPort;

    @Value("${spring.data.mongodb.database}")
    private String mongoDB;

    @Override
    public MongoDbFactory mongoDbFactory() {
        return new SimpleMongoDbFactory(new MongoClient(mongoHost + ":" + mongoPort), mongoDB);
    }

    @Override
    public MongoClient mongoClient() {
        return new MongoClient(mongoHost, Integer.parseInt(mongoPort));
    }

    @Override
    public MongoTemplate mongoTemplate() {
        return new MongoTemplate(mongoDbFactory());
    }

    @Override
    public MappingMongoConverter mappingMongoConverter() {
        return new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory()), new MongoMappingContext());
    }

    @Override
    protected String getDatabaseName() {
        return mongoDB;
    }
}

PersonКласс сбора

@Document
public class Person {
    @Id
    private String id;

    private String name;

    @CreatedDate
    private LocalDateTime createdAt;
    @LastModifiedDate
    private LocalDateTime lastModified;
    // Getter Setters Constructors omitted for brevity
}

Основной класс приложения

@EnableMongoAuditing
@EnableMongoRepositories ({"com.example.*", "org.apache.*"})
@SpringBootApplication
@ComponentScan({"com.example.*", "org.apache.*"})
public class DemoApplication implements CommandLineRunner {

    @Autowired
    PersonRepository personRepository;
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        Person p1 = new Person("1", "prakhar");
        personRepository.save(p1);

    }
}

Ожидаемый результат: сущность Person должна быть сохранена в базе данных.Фактический результат: « Не удалось найти PersistentEntity для класса типа Person » Ошибка

1 Ответ

1 голос
/ 03 мая 2019

Похоже, вы столкнулись с https://github.com/spring-projects/spring-boot/issues/12023

Расширение AbstractMongoConfiguration отключит автоматическую настройку Spring Boot различных компонентов Mongo, а также настроит базовые пакеты, которые используются для сканирования на соответствие.Я бы порекомендовал вам не использовать его в Spring Boot.

Обновление

Мне удалось запустить пример с такой простой конфигурацией, как

@Configuration
public class MongoConfig {

    @Value("${spring.data.mongodb.host}")
    private String mongoHost;

    @Value("${spring.data.mongodb.port}")
    private String mongoPort;

    @Value("${spring.data.mongodb.database}")
    private String mongoDB;

    @Bean
    public MongoDbFactory mongoDbFactory() {
        return new SimpleMongoDbFactory(new MongoClient(mongoHost + ":" + mongoPort), mongoDB);
    }

    @Bean
    public MongoClient mongoClient() {
        return new MongoClient(mongoHost, Integer.parseInt(mongoPort));
    }
}

и класс приложения

@EnableMongoAuditing
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

    @Autowired
    PersonRepository personRepository;
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        Thread.sleep(2000);
        Person p1 = new Person("1", "prakhar");
        personRepository.save(p1);

    }
}

Обратите внимание, что я последовал собственному совету и не унаследовал от AbstractMongoConfiguration

Объяснение

Проблема заключается в инициализации

 @Bean
 public MappingMongoConverter mappingMongoConverter() {
     return new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory()), new MongoMappingContext());
}

Вы просто вызываете конструктор MongoMappingContext, не вызывая setInitialEntitySet.Сравните это с MongoDataConfiguration классом автоконфигурации.

@Bean
@ConditionalOnMissingBean
public MongoMappingContext mongoMappingContext(MongoCustomConversions conversions)
        throws ClassNotFoundException {
    MongoMappingContext context = new MongoMappingContext();
    context.setInitialEntitySet(new EntityScanner(this.applicationContext)
            .scan(Document.class, Persistent.class));
    Class<?> strategyClass = this.properties.getFieldNamingStrategy();
    if (strategyClass != null) {
        context.setFieldNamingStrategy(
                (FieldNamingStrategy) BeanUtils.instantiateClass(strategyClass));
    }
    context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
    return context;
}

Еще хуже, вы не зарегистрируете MongoMappingContext в качестве управляемого компонента.В связи с этим класс автоконфигурации все еще создается.Это приводит к состоянию гонки, я пытался запустить оригинальный код и мог легко воспроизвести ошибку, но с точкой останова в AbstractMappingContext.addPersistentEntity тест всегда проходил.

...