使用@EnableMongoAuditing时无法找到类型类的PersistentEntity

问题描述 投票:0回答:2

当我将 @EnableMongoAuditing 功能与 MongoRepository 一起使用时,出现“

无法找到类型类的 PersistentEntity 
”错误。 当我在数据库中尚不存在集合时保存文档时,会发生这种情况。

我尝试了以下内容:

但没有任何效果。

提到的事情是:

通过 AbstractMongoConfiguration 扩展 MongoConfig 并覆盖所有方法。

这是我的代码,它重现了相同的错误:

MongoConfig 类

@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;
    }
}

人物集合类

@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 实体应保存在数据库中。 实际结果是“无法找到类型类 Person 的 PersistentEntity”错误

spring-boot spring-data-mongodb
2个回答
4
投票

看起来你遇到了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
注册为托管 bean。 因此,仍然会创建自动配置类。这导致了竞争条件,我尝试运行原始代码并且可以轻松地重现错误,但是在
AbstractMappingContext.addPersistentEntity
中设置断点,测试总是通过。


0
投票

对我来说,如果您的类从

MongoConfig
 扩展,我通过在 
AbstractMongoConfiguration

中添加以下方法解决了这个问题
@Override
protected String getMappingBasePackage() {
   return "com.companyName.modulename"
}

如果

MongoConfig
MongoConfigurationSupport
延伸,则添加以下方法

@Override
protected Collection<String> getMappingBasePackages() {
   return Arrays.asList("com.companyName.module1","com.companyName.module2");
}

请注意,在后面的情况下,我可以指定多个包名称作为基础包。

© www.soinside.com 2019 - 2024. All rights reserved.