How do you use both Spring Data JPA and Spring Data Elasticsearch repositories on the same domain class in a Spring Boot application?

Johnny Lim picture Johnny Lim · Oct 1, 2015 · Viewed 9.7k times · Source

I'm trying to use both Spring Data JPA and Spring Data Elasticsearch on the same domain object but it doesn't work.

When I tried to run a simple test, I got the following exception:

org.springframework.data.mapping.PropertyReferenceException: No property index found for type Person! at org.springframework.data.mapping.PropertyPath.(PropertyPath.java:75) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:270) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:241) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.repository.query.parser.Part.(Part.java:76) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.repository.query.parser.PartTree$OrPart.(PartTree.java:235) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:373) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.repository.query.parser.PartTree$Predicate.(PartTree.java:353) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.repository.query.parser.PartTree.(PartTree.java:84) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.(PartTreeJpaQuery.java:61) ~[spring-data-jpa-1.9.0.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:95) ~[spring-data-jpa-1.9.0.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:206) ~[spring-data-jpa-1.9.0.RELEASE.jar:na] at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:73) ~[spring-data-jpa-1.9.0.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.(RepositoryFactorySupport.java:408) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:206) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:251) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:237) ~[spring-data-commons-1.11.0.RELEASE.jar:na] at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) ~[spring-data-jpa-1.9.0.RELEASE.jar:na] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) ~[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE] ... 43 common frames omitted

They work when disabling either one.

The project is based on Spring Boot 1.3.0.M5.

This is a sample project reproducing the situation:

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

Answer

Kenny Bastani picture Kenny Bastani · Oct 1, 2015

Repositories in Spring Data are datasource agnostic, meaning that JpaRepository and ElasticsearchRepository both roll up into Repository interface. When this is the case, then auto-configuration of Spring Boot will cause Spring Data JPA to try and configure a bean for each repository in the project that inherits any Spring Data Commons base repository.

To fix this problem you need to move your JPA repository and Elasticsearch repository to separate packages and make sure to annotate your @SpringBootApplication application class with:

  • @EnableJpaRepositories
  • @EnableElasticsearchRepositories

Then you need to specify where the repositories are for each enable annotation. This ends up looking like:

@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);
    }

}

Then your application will be able to disambiguate which repositories are intended for which Spring Data project.