使用@EnableMongoAuditing时找不到类型类的PersistentEntity

时间:2019-04-30 07:07:51

标签: spring-boot spring-data-mongodb

当我将@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 ”错误

2 个答案:

答案 0 :(得分:1)

好像您遇到了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中使用断点,测试始终可以通过。

答案 1 :(得分:0)

对于我来说,如果您的课程从MongoConfig扩展过来,我会在AbstractMongoConfiguration中添加以下方法来解决此问题

@Override
protected String getMappingBasePackage() {
 return "com.companyName.modulename"

}

如果MongoConfigMongoConfigurationSupport扩展,则添加以下方法

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

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