Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 268
Johnny Lim Avatar asked Oct 01 '15 03:10

Johnny Lim


People also ask

Can we have two repositories in spring boot?

You can only have one repository per entity... however, you can have multiple entities per table; thus, having multiple repositories per table.

Can we use Spring data JPA and Hibernate together?

You cant actually use both of them in the same application. For backwards compatibility. We are expanding our application and want to start using Spring Data JPA, but still keep the old hibernate implementation. Its better you develop your new application as a separate microservice and use spring data jpa ..

How does JPA connect to multiple databases in spring boot?

To connect multiple databases, each database should be configured in its own spring boot configuration file. Multiple data sources should be configured for multiple databases. For spring data classes and spring data JPA repositories, two separate java packages need be created.

Is JPA and Spring data JPA same?

Spring data jpa- it is same like jpa means we can describe in below way. Spring Data Jpa is jpa data abstraction access which means it likes a jpa but it add some extra functionality, Without jpa we can not implement the spring data jpa.


2 Answers

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.

like image 127
Kenny Bastani Avatar answered Sep 29 '22 04:09

Kenny Bastani


You can use like this:

@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 {
    ...
}

Or in 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 {
    ...
}
like image 23
Efriandika Pratama Avatar answered Sep 29 '22 02:09

Efriandika Pratama