Spring 数据 Elasticsearch 自定义存储库

Spring Data Elasticsearch cusom repository

在我的 Spring 启动应用程序中,我试图通过 Elasticsearch 实现模糊搜索。

这是我的 ES 配置:

@Profile("test")
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.example.domain.repository.elasticsearch")
public class ElasticsearchTestConfig {
}

我有一个存储库:

@Repository
public interface ESDecisionRepository extends ElasticsearchRepository<ESDecision, String>, ESDecisionRepositoryCustom {
}

为了能够进行模糊搜索,我创建了一个自定义存储库:

public interface ESDecisionRepositoryCustom {

    public List<ESDecision> findFuzzyBySearchTerm(String searchTerm);

}

并提供了自定义实现:

@Repository
public class ESDecisionRepositoryCustomImpl implements ESDecisionRepositoryCustom {

    @Autowired
    protected ElasticsearchTemplate elasticsearchTemplate;

    @Override
    public List<ESDecision> findFuzzyBySearchTerm(String searchTerm) {
        Criteria c = new Criteria("name").fuzzy(searchTerm);
        return elasticsearchTemplate.queryForList(new CriteriaQuery(c), ESDecision.class);
    }

}

现在在启动过程中,我的应用程序失败并出现以下异常:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ESDecisionRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.PropertyReferenceException: No property searchTerm found for type ESDecision!
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory.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.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 43 common frames omitted
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property searchTerm found for type ESDecision!
    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:247)
    at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:398)
    at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:378)
    at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:89)
    at org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery.<init>(ElasticsearchPartQuery.java:44)
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactory$ElasticsearchQueryLookupStrategy.resolveQuery(ElasticsearchRepositoryFactory.java:119)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:436)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:221)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:277)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:263)
    at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean.afterPropertiesSet(ElasticsearchRepositoryFactoryBean.java:67)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
    ... 53 common frames omitted

我做错了什么以及如何解决?

将您的自定义存储库实现 class 名称从 ESDecisionRepositoryCustomImpl 更改为 ESDecisionRepositoryImpl

来自文档

The most important bit for the class to be found is the Impl postfix of the name on it compared to the core repository interface (see below).

必须遵循命名约定才能使自定义存储库实现正常工作。查看 docs

试试这个:

@Repository
public class ESDecisionRepositoryCustomImpl implements ESDecisionRepositoryCustom {

     @Autowired
     protected ElasticsearchTemplate elasticsearchTemplate;

     @Override
     public List<ESDecision> findFuzzyBySearchTerm(String searchTerm) {
         Criteria c = new Criteria("name").fuzzy(searchTerm);
         return elasticsearchTemplate.queryForList(new CriteriaQuery(c), ESDecision.class);
     }

}

希望对您有所帮助。