【问题标题】:MappingException: Couldn't find PersistentEntity while implementing AbstractElasticsearchConfigurationMappingException:在实现 AbstractElasticsearchConfiguration 时找不到 PersistentEntity
【发布时间】:2020-10-09 18:10:54
【问题描述】:

我想在this guidethis 回答之后为我的对象实现自定义转换器,但是当我运行项目时我收到 MappingException: Couldn't find PersistentEntity for type class TransactionElastic

这是我的配置

@Configuration
public class ElasticConfig extends AbstractElasticsearchConfiguration {


    @Value("$elasticUrl")
    private String elasticUrl;

    @Override
    public RestHighLevelClient elasticsearchClient() {
        return RestClients.create(ClientConfiguration.create(elasticUrl)).rest();
    }

    @Bean
    public EntityMapper entityMapper() {
        ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(), new DefaultConversionService());
        entityMapper.setConversions(elasticsearchCustomConversions());
        return entityMapper;
    }

    @Bean
    @Override
    public ElasticsearchCustomConversions elasticsearchCustomConversions() {
        return new ElasticsearchCustomConversions(Arrays.asList(new TransactionToMapConverter(), new MapToTransactionConverter()));
    }
}

@WritingConverter
public class TransactionToMapConverter implements Converter<TransactionElastic, Map<String, Object>> {
    @Override
    public Map<String, Object> convert(TransactionElastic tradeTransaction) {
        Map<String, Object> target = new HashMap<>();
        target.put("id", tradeTransaction.getId());
        target.put("portfolio_name", tradeTransaction.getPortfolioName());
        target.put("settl_date", tradeTransaction.getSettlDate());
        return target;
    }
}
@ReadingConverter
public class MapToTransactionConverter implements Converter<Map<String, Object>, TransactionElastic> {
    @Override
    public TransactionElastic convert(Map<String, Object> map) {
        TransactionElastic t = new TransactionElastic();
        t.setPortfolioName(map.get("portfolio_name").toString());
        t.setId((Long) map.get("id"));
        return t;
    }
}

@Document(indexName = "transactions")
public class TransactionElastic {
    @Id
    private Long id;
    @Field(name = "portfolio_name", type = FieldType.Text)
    private String portfolioName;
    @Field(name = "settl_date", type = FieldType.Date)
    private Date settlDate;
    @Field(name = "trscn_status", type = FieldType.Text)
    private String trscnStatus;
    // getters and setters here 
}

堆栈跟踪

15:49:41.488 [restartedMain] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'techNeedsController': Unsatisfied dependency expressed through field 'elasticService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'transactionServiceElastic': Unsatisfied dependency expressed through field 'transactionElasticRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionElasticRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class com.portal.domain.TransactionElastic!
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:397)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1429)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
    at com.portal.Application.main(Application.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'transactionServiceElastic': Unsatisfied dependency expressed through field 'transactionElasticRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionElasticRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class com.portal.domain.TransactionElastic!
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:397)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1429)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:636)
    ... 24 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionElasticRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class com.portal.domain.TransactionElastic!
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1803)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:636)
    ... 37 common frames omitted
Caused by: org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class com.portal.domain.TransactionElastic!
    at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:79)
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchEntityInformationCreatorImpl.getEntityInformation(ElasticsearchEntityInformationCreatorImpl.java:49)
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactory.getEntityInformation(ElasticsearchRepositoryFactory.java:67)
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactory.getTargetRepository(ElasticsearchRepositoryFactory.java:72)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:312)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:297)
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:212)
    at org.springframework.data.util.Lazy.get(Lazy.java:94)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:300)
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean.afterPropertiesSet(ElasticsearchRepositoryFactoryBean.java:67)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1862)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1799)
    ... 47 common frames omitted

注册转换器日志

o.s.data.convert.CustomConversions - Registering converter from class com.portal.domain.TransactionElastic to interface java.util.Map as writing converter although it doesn't convert to a store-supported type! You might wanna check you annotation setup at the converter implementation.
o.s.data.convert.CustomConversions - Registering converter from interface java.util.Map to class com.portal.domain.TransactionElastic as reading converter although it doesn't convert from a store-supported type! You might wanna check you annotation setup at the converter implementation.
o.s.data.convert.CustomConversions - Registering converter from class org.springframework.data.geo.Point to interface java.util.Map as writing converter although it doesn't convert to a store-supported type! You might wanna check you annotation setup at the converter implementation.
o.s.data.convert.CustomConversions - Registering converter from interface java.util.Map to class org.springframework.data.geo.Point as reading converter although it doesn't convert from a store-supported type! You might wanna check you annotation setup at the converter implementation.
o.s.data.convert.CustomConversions - Registering converter from class org.springframework.data.elasticsearch.core.geo.GeoPoint to interface java.util.Map as writing converter although it doesn't convert to a store-supported type! You might wanna check you annotation setup at the converter implementation.
o.s.data.convert.CustomConversions - Registering converter from interface java.util.Map to class org.springframework.data.elasticsearch.core.geo.GeoPoint as reading converter although it doesn't convert from a store-supported type! You might wanna check you annotation setup at the converter implementation.
o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning

Spring Boot 2.2.1 版 Spring数据弹性搜索3.2.1 Elasticsearch 6.4.0 版

什么可能导致问题?我错过了什么吗?

【问题讨论】:

  • 你能发布堆栈跟踪吗?
  • 嗨@SimonMartinelli,我已经更新了问题,添加了stacktrace
  • 你的包结构是什么样的?
  • com.portal.domain - 用于@Document 对象 com.portal.search - elasticsearch 存储库 com.portal.service - 用于服务接口和实现 com.portal.config - 带有配置 com.portal.converter - 带转换器
  • SpringBootApplication在哪个包中?

标签: java spring-boot spring-data-elasticsearch


【解决方案1】:

我认为它无法找到实体。请在AbstractElasticsearchConfiguration中扩展以下方法:

@Override
protected Collection<String> getMappingBasePackages() {
    //Provide list of your packages where you have entities.
}

【讨论】:

  • 更新了我的配置,如下@Override protected Collection getMappingBasePackages() { return Collections.singletonList("com.meritkapital.portal.domain"); } 但仍然有同样的异常
  • 我还建议尝试创建一个简单的配置 bean,而不是扩展 AbstractElasticsearchConfiguration,因为它会禁用一些自动配置。无需扩展它,只需创建一个配置 bean 并根据您的需要创建方法级别的 bean。
  • 感谢您的建议。试图在配置中只保留 Elasticsearch CustomConversions 方法 bean,但没有帮助。
【解决方案2】:

Spring Boot 开发工具

你在使用 Spring Boot 开发工具吗? DevTools 可能会导致您看到的 MappingException 错误,因为它使用了多个类加载器。

一种解决方法是使用 application.properties 或 application.yml 中的 spring.devtools.additional-exclude 属性排除映射包,如下所示:

spring.devtools.additional-exclude: static/**,com.portal.domain/**

更激进的方法是停止使用 devtools,但这样做会禁用 LiveReload 功能,这在开发过程中很不错:

在 Maven 的 pom.xml 中:

<!-- <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-devtools</artifactId>
 <optional>true</optional>
</dependency> -->

在 Gradle 的 build.gradle 中:

/* compileOnly("org.springframework.boot:spring-boot-devtools") */

Devtools 仅用于开发,不应在生产代码中默认禁用。因此,如果这是错误,那么您的代码在生产中部署时应该可以工作。

原因

错误的原因似乎在 DefaultReactiveIndexOperations 中的这个 sn-p 代码中:

    private IndexCoordinates getIndexCoordinatesFor(Class<?> clazz) {
        return operations.getElasticsearchConverter().getMappingContext().getRequiredPersistentEntity(clazz)
                .getIndexCoordinates();
    }

getRequiredPersisentEntity(clazz) 的调用失败,因为它在类-> PersistentEntities 的映射中查找clazz,并且由于单独的类加载器,类不同。

我不知道为什么映射类是在单独的类加载器中加载的。

【讨论】:

    猜你喜欢
    • 2018-07-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 2019-12-14
    • 2019-04-05
    相关资源
    最近更新 更多