在Spring Boot应用中如何在同一个领域类上同时使用Spring Data JPA和Spring Data Elasticsearch存储库?

17
我将尝试为您翻译以下编程相关内容:

我正在尝试在同一领域对象上同时使用Spring Data JPA和Spring Data Elasticsearch,但是它无法正常工作。

当我尝试运行简单的测试时,我遇到了以下异常:

org.springframework.data.mapping.PropertyReferenceException: 找不到Person类型的属性索引!在org.springframework.data.mapping.PropertyPath.(PropertyPath.java:75) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]和org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中创建,在org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]和org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中, 在org.springframework.data.repository.query.parser.Part.(Part.java:76) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.repository.query.parser.PartTree$OrPart.(PartTree.java:235) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.repository.query.parser.PartTree$Predicate.(PartTree.java:353) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.repository.query.parser.PartTree.(PartTree.java:84) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.jpa.repository.query.PartTreeJpaQuery.(PartTreeJpaQuery.java:61) ~ [spring-data-jpa-1.9.0.RELEASE.jar:na]中,在org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:95) ~ [spring-data-jpa-1.9.0.RELEASE.jar:na]中,在org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:206) ~ [spring-data-jpa-1.9.0.RELEASE.jar:na]中,在org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:73) ~ [spring-data-jpa-1.9.0.RELEASE.jar:na]中,在org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.(RepositoryFactorySupport.java:408) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:206) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237) ~ [spring-data-commons-1.11.0.RELEASE.jar:na]中,在org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) ~ [spring-data-jpa-1.9.0.RELEASE.jar:na]中,在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) ~ [spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE]中,在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~ [spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE]中,省略了43个常见框架。
他们在禁用其中一个时工作。
该项目基于Spring Boot 1.3.0.M5。
这是一个重现情况的示例项目。

https://github.com/izeye/spring-boot-throwaway-branches/tree/data-jpa-and-elasticsearch

2个回答

30

Spring Data中的存储库是与数据源无关的,这意味着JpaRepositoryElasticsearchRepository都卷入到Repository接口中。当情况是这样时,Spring Boot的自动配置将导致Spring Data JPA尝试为项目中继承任何Spring Data Commons基本存储库的每个存储库配置一个bean。

要解决此问题,您需要将JPA存储库和Elasticsearch存储库移动到单独的包中,并确保在您的@SpringBootApplication应用程序类上进行注释:

  • @EnableJpaRepositories
  • @EnableElasticsearchRepositories

然后,您需要为每个启用注释指定存储库所在位置。最终看起来像:

@SpringBootApplication
@EnableJpaRepositories("com.izeye.throwaway.data")
@EnableElasticsearchRepositories("com.izeye.throwaway.indexing")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

然后您的应用程序将能够区分哪些存储库是为哪个Spring Data项目而设计的。


1
谢谢提供详细信息,这给了我一个思路,最终我选择使用 includeFilters 而不是将它们移动到另一个包中。Spring Data 的数据源无关性非常好,但如果可能的话,希望 Spring Data JPA 不要扫描 ElasticsearchRepository 接口。 - Johnny Lim
4
如果有人对我所做的事情感兴趣,请查看https://github.com/izeye/spring-boot-throwaway-branches/commit/874ccba09189d6ef897bc430c43b6e3705404399 - Johnny Lim
感谢kenny-bastani和johnny-lim,我都给你们点赞了。 - Eddie Jaoude

6
您可以像这样使用:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchCrudRepository.class))
@EnableElasticsearchRepositories(includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchCrudRepository.class))
public class DataConfiguration {
    ...
}

或者在SpringBoot中:

@SpringBootApplication
@EnableJpaRepositories(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchCrudRepository.class))
@EnableElasticsearchRepositories(includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchCrudRepository.class))
public class MyApplication {
    ...
}

@EnableJpaRepositories中,我们应该使用JpaRepository.class而不是ElasticsearchCrudRepository.class,对吗? - edwin
因为我在@EnableJpaRepositories中使用了exclude,所以在Jpa Repository中,你不仅可以使用JpaRepository.class - Efriandika Pratama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接