zoukankan      html  css  js  c++  java
  • springboot使用elasticsearch报No property index found for type错误

    一、前提:项目之前使用springboot+spring-data-mongodb。现在需要加入elasticsearch做搜索引擎,这样mongo和elasticsearch共存了。

    二、报错信息:

    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'TTSAudioInfoEsRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property index found for type TTSAudioInfo!
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1082)
        at org.springframework.data.repository.support.Repositories.cacheRepositoryFactory(Repositories.java:95)
        at org.springframework.data.repository.support.Repositories.populateRepositoryFactoryInformation(Repositories.java:88)
        at org.springframework.data.repository.support.Repositories.<init>(Repositories.java:81)
        at org.springframework.data.repository.support.DomainClassConverter.setApplicationContext(DomainClassConverter.java:98)
        at org.springframework.data.web.config.SpringDataWebConfiguration.addFormatters(SpringDataWebConfiguration.java:87)
        at org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite.addFormatters(WebMvcConfigurerComposite.java:49)
        at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration.addFormatters(DelegatingWebMvcConfiguration.java:117)
        at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.mvcConversionService(WebMvcConfigurationSupport.java:542)
        at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$f6948e02.CGLIB$mvcConversionService$45(<generated>)
        at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$f6948e02$$FastClassBySpringCGLIB$$43c05aaf.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
        at org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$f6948e02.mvcConversionService(<generated>)
        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.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
        ... 73 common frames omitted
    Caused by: org.springframework.data.mapping.PropertyReferenceException: No property index found for type TTSAudioInfo!
        at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:77)
        at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:329)
        at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:309)
        at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:272)
        at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:243)
        at org.springframework.data.repository.query.parser.Part.<init>(Part.java:76)
        at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:235)
        at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373)
        at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:353)
        at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:84)
        at org.springframework.data.mongodb.repository.query.PartTreeMongoQuery.<init>(PartTreeMongoQuery.java:60)
        at org.springframework.data.mongodb.repository.support.MongoRepositoryFactory$MongoQueryLookupStrategy.resolveQuery(MongoRepositoryFactory.java:168)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:435)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:220)
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:266)
        at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:252)
        at org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean.afterPropertiesSet(MongoRepositoryFactoryBean.java:108)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
        ... 98 common frames omitted

    三、错误分析:

      1、TTSAudioInfo类是pojo类,既是mongo的document也是elasticsearch的document

    /**
     * @author: george
     * @date: 2018/6/26-16-39
     * @description:
     */
    @org.springframework.data.elasticsearch.annotations.Document(indexName = "tts_audio_info", type = "tts_audio_info") //spring-data-elasticsearch注解
    @org.springframework.data.mongodb.core.mapping.Document(collection = "TTSAudioInfo") //spring-data-mongodb注解
    @Data  //lombok注解
    public class TTSAudioInfo extends BaseModel {
        private static final long serialVersionUID = 1L;
        public static final String FIELD_QUESTION = "question";
        public static final String FIELD_ANSWER = "answer";
        public static final String FIELD_FILE_URI = "fileUri";
        public static final String FIELD_FILE_PATH = "filePath";
    
        private String question;
        @Field(type = FieldType.String, index = FieldIndex.analyzed)
        private String answer;
        private String fileUri;
        private String filePath;
    
        public TTSAudioInfo() {
        }
    }

      2、然后是elasticsearch的repository接口,继承的是ElasticsearchRepository

    import ai.deepbrain.admin.domain.TTSAudioInfo;
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    
    /**
     * @author: george
     * @date: 2018/6/26-17-05
     * @description:
     */
    public interface TTSAudioInfoEsRepository extends ElasticsearchRepository<TTSAudioInfo, String> {
    }

      

    分析:spring-data-mongo和spring-data-elasticsearch都属于spring的spring-data项目,提供各种数据库数据访问的封装(mongo、redis、oracle、mysql、jpa、elasticsearch等等等等)。他们封装的格式基本一样;

    而在本文的错误中,我们使用了mongodb和elasticsearch,我们在查看TTSAudioInfoEsRepository继承的ElasticsearchCrudRepository的继承关系后得知,他和MongoRepository都继承spring-data-commons的PagingAndSortingRepository。

    (这里还有一点就是所有repository接口写在同一包下)所以导致了在mongodb扫描repository的时候也会扫描elasticsearch的repository,spring-data-mongodb会试图代理TTSAudioInfoEsRepository ,但是发现TTSAudioInfoEsRepository 使用的TTSAudioInfo中没有index属性,从而报错No property index found for type。

    stackoverflow中有一篇类似的错误文章:https://stackoverflow.com/questions/36252099/no-property-index-found-for-type-user。

    四、解决办法:

    既然知道错误的原因了,那解决起来就相对简单了。无非就是让spring-data-mongo扫描mongodb的repository,spring-data-elasticsearch扫描elasticsearch的repository。

    1、把不同类型的repository分别放在不同包下,然后在配置的地方指定扫描位置

      mongodb的配置类

    @Configuration
    @Import(value = MongoAutoConfiguration.class)
    @EnableMongoRepositories(basePackages = "com.test.mongodb")
    public class MongoConfiguration extends AbstractMongoConfiguration {
    
        @Autowired
        private MongoProperties mongoProperties;
    
        @Override
        protected String getDatabaseName() {
            return mongoProperties.getDatabase();
        }
    
        @Override
        public Mongo mongo() throws Exception {
            MongoClientURI clientURI = new MongoClientURI(mongoProperties.getUri());
            return new MongoClient(clientURI);
        }
    
        @Bean
        public ValidatingMongoEventListener validatingMongoEventListener() {
            return new ValidatingMongoEventListener(validator());
        }
    
        @Bean
        public LocalValidatorFactoryBean validator() {
            return new LocalValidatorFactoryBean();
        }
    
        @Bean
        public MappingMongoConverter mappingMongoConverter() throws Exception {
            DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
            MappingMongoConverter converter = new MappingMongoConverter(dbRefResolver, mongoMappingContext());
            // remove _class field
            converter.setTypeMapper(new DefaultMongoTypeMapper(null));
            converter.setCustomConversions(customConversions());
            return converter;
        }
    }

      elasticsearch的配置类

    @Configuration
    @EnableElasticsearchRepositories(basePackages = "com.test.elasticsearch")
    public class ElasticsearchConfiguration {
    
        @Bean
        public ElasticsearchTemplate elasticsearchTemplate(Client client,
                                                           Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) {
            MappingElasticsearchConverter converter = new MappingElasticsearchConverter(
                    new SimpleElasticsearchMappingContext());
            DefaultResultMapper mapper = new DefaultResultMapper(converter.getMappingContext(),
                    new CustomEntityMapper(jackson2ObjectMapperBuilder.createXmlMapper(false).build()));
            return new ElasticsearchTemplate(client, converter, mapper);
        }
    
        public class CustomEntityMapper implements EntityMapper {
    
            private ObjectMapper objectMapper;
    
            public CustomEntityMapper(ObjectMapper objectMapper) {
                this.objectMapper = objectMapper;
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
            }
    
            @Override
            public String mapToString(Object object) throws IOException {
                return objectMapper.writeValueAsString(object);
            }
    
            @Override
            public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
                return objectMapper.readValue(source, clazz);
            }
        }
    }

    2、在配置enabled注解的时候添加includeFilters

    mongo:

    @Configuration
    @Import(value = MongoAutoConfiguration.class)
    @EnableMongoRepositories(basePackages = "com.test",includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MongoRepository.class))
    public class MongoConfiguration extends AbstractMongoConfiguration {

    elasticsearch:

    @Configuration
    @EnableElasticsearchRepositories(basePackages = "com.test",includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchRepository.class))
    public class ElasticsearchConfiguration {
  • 相关阅读:
    Django---Django的中间件
    Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)
    Django---ORM的常用字段和自定义字段,DjangoORM字段与数据库类型对应,字段参数和Meta的参数,Django的admin操作,13中orm操作方法,单标的双下方法
    Django---路由系统,URLconf的配置,正则表达式的说明(位置参数),分组命名(捕获关键字参数),传递额外的参数给视图,命名url和url的反向解析,url名称空间
    Django---CBV和FBV的使用,CBV的流程,给视图加装饰器,Request对象方法,属性和Response对象,form表单的上传
    Django---图书管理系统,多对多(ManyToMany),request获取多个值getlist(),反查(被关联的对象.author_set.all)
    Django---简易图书管理系统(B/S架构)
    从Base64编码转换为图片文件
    图片转化成base64字符串
    设置Linux的一些文本输出方式
  • 原文地址:https://www.cnblogs.com/shuaiqing/p/9233174.html
Copyright © 2011-2022 走看看