【问题标题】:Couldn't find PersistentEntity for type class when using @EnableMongoAuditing使用 @EnableMongoAuditing 时找不到类型类的 PersistentEntity
【发布时间】:2019-04-30 07:07:51
【问题描述】:

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


    【解决方案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 中有一个断点,测试总是通过。

    【讨论】:

    • 我的眼睛一定让我失望了。我可以在您的问题中看到github.com/spring-projects/spring-boot/issues/10312,但这不是同一个问题
    • 其实我的意思是只报告这个问题,由于错误我报告了错误的问题,我将编辑问题。
    • 它并没有解决拥有Mongo模板和Mongo审计功能的问题。
    • 用一个工作示例和解释更新了答案
    • 谢谢,我正在寻找的东西
    【解决方案2】:

    对我来说,如果您的类从 AbstractMongoConfiguration 扩展,我通过在 MongoConfig 中添加以下方法解决了这个问题

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

    }

    如果 MongoConfig 扩展自 MongoConfigurationSupport 则添加以下方法

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

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

    【讨论】:

      猜你喜欢
      • 2019-07-27
      • 2019-12-14
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 2021-10-26
      • 2020-10-09
      • 2021-11-29
      • 2014-01-25
      相关资源
      最近更新 更多