Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring - Multiple Spring Data modules found, entering strict repository configuration mode

I am using Spring boot 2 with Spring Data, Spring-Data-Elastisearch and Spring-data-Redis(for http sessions). When i start the app. I'm receiving

2017-10-29 17:38:33.376  INFO 18625 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2017-10-29 17:38:33.451  INFO 18625 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2017-10-29 17:38:33.461  INFO 18625 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2017-10-29 17:38:33.768  INFO 18625 --- [  restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2017-10-29 17:38:33.783  INFO 18625 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.ecommerce.core.repository.elastic.ProductElasticSearchRepository.
2017-10-29 17:38:33.787  INFO 18625 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.ecommerce.core.repository.jpa.UserRepository.
2017-10-29 17:38:33.790  INFO 18625 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.ecommerce.core.repository.jpa.catalog.CategoryJsonWrapperRepository.
2017-10-29 17:38:33.793  INFO 18625 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.ecommerce.core.repository.jpa.catalog.CategoryRepository.
2017-10-29 17:38:33.794  INFO 18625 --- [  restartedMain] .RepositoryConfigurationExtensionSupport : Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.ecommerce.core.repository.jpa.catalog.ProductRepository.

In my App.java file, i have the following lines (which should avoid the ambiguity)

@EnableJpaRepositories(basePackages = {"com.ecommerce.core.repository.jpa"})
@EnableElasticsearchRepositories(basePackages= {"com.ecommerce.core.repository.elastic"})
@EnableRedisRepositories(basePackages = {"org.springframework.data.redis.connection.jedis"})

Every spring data repository extends specific for his job Interface (mainly JpaRepository and one of ElasticsearchCrudRepository

I read this -https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.multiple-modules.types and as you can see, everything should work without issues.

like image 221
ROZZ Avatar asked Oct 29 '17 15:10

ROZZ


People also ask

Can we have multiple repository 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.

Which of the following values can be used to configure a BootstrapMode with JPA considering JPA 2.1 or above?

As of Spring Data JPA 2.1 you can now configure a BootstrapMode (either via the @EnableJpaRepositories annotation or the XML namespace) that takes the following values: DEFAULT (default) — Repositories are instantiated eagerly unless explicitly annotated with @Lazy .

What is the use of @EnableJpaRepositories?

Spring Data Jpa provides EnableJpaRepositories annotation which is used to scan the packages for configuration and repository class for Spring Data JPA.


Video Answer


4 Answers

Since you are explicitly enabling the repositories on specific packages. You can include this in the application.properties to avoid these errors:

spring.data.redis.repositories.enabled=false

You can do the same for the other repositories as well. If you encounter similar errors:

spring.data.elasticsearch.repositories.enabled=false
spring.data.jpa.repositories.enabled=false

Reference: https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html

like image 161
Nikhil Avatar answered Oct 20 '22 20:10

Nikhil


Your configurations are all right. The problem is caused by RedisRepositoriesAutoConfiguration. It registers EnableRedisRepositories repeatedly only with default config, which with empty basePackages.

To solve the problem, you could exclude RedisRepositoriesAutoConfiguration by:

@SpringBootApplication(
        exclude = { RedisRepositoriesAutoConfiguration.class }
)
public class MySpringBootApp {

}
like image 45
Hank Avatar answered Oct 20 '22 18:10

Hank


Sorry for answering too late, but I think answers that present already does not explain the actual, deep reason why is it happening. Let me explain everything in order to let you understand the guts (be ready, it will be quite long and comprehensive). If you are looking for simple solution, go to the bottom of my answer:

First of all, the spring data, as a general module (forget about particular modules, like spring data jpa, or spring data redis), has an hierarcy of interfaces. It begins from Repository, then comes CrudRepository, and after that there is PagingAndSortingRepository. I will not get into details about the difference between them, this is not the point now. What is important - this interfaces are absolutely segregated from the particular persistence storage, just becuase they are technically resides within the separate JAR that shipps right away with any particular spring data implementation (it is called spring-data-commons, see official doc, if you are interested)

What do I mean - you can use Spring data module for MongoDB. In order to take advantage of spring data mongodb what would you typically do: right, extend the CrudRepository, or Repository or MongoRepository. It is very important - from the spring-data perspective, if you create your own interface by extending Repository, or CrudRepository and you did not marked the target repository entity anyhow (I will explain at the end of the answer), then Spring will basically try to find out by itself, how exactly this magical methods: findById, deleteById and e.t.c. must by implemented, becuase obviously thier implementation will be different in Mongo and in JPA. With this in mind, read on.

The question is - how exactly spring determines, the way you custom interfaces must be implemented? Well, there is an abstraction within the Spring guts, called RepositoryFactoryBeanSupport. This is the thing that actually participate in beans creation from your custom repositories. Lets make an experiment now: Try out add both spring data jdbc starter and spring data mongodb starter into your project. You will notice, that in your classpath there are 2 diffrenet implementations of RepositoryFactoryBeanSupport:

  1. JdbcRepositoryFactoryBean (comes from spring data jdbc starter)
  2. MongoRepositoryFactoryBean (comes from spring data mongo starter)

Then, lets assume, that I have an entity, like this:

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Customer {

    @Id
    private Long id;

    @Column("firstname")
    private String firstName;

    @Column("phone")
    private String phone;
}

Also note: the Id and the Column annotations are actually spring data annotations, not JPA.

Then lets define an interface (simple dao interface):

public interface CustomerCRUDRepository extends CrudRepository<Customer, Long> {
    int countByFirstName(String firstName);
}

And now, inject the bean of type CustomerCRUDRepository somewhere. Just try to bootstrap the application - you will fail. Why? Let`s investigate the logs together:

RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!

RepositoryConfigurationDelegate : Bootstrapping Spring Data JDBC repositories in DEFAULT mode

RepositoryConfigurationExtensionSupport : Spring Data JDBC - Could not safely identify store assignment for repository candidate interface com.example.springdatajdbc.repositories.CustomerCRUDRepository

The same exception as in your question, is not it? Let us finally break this down. Now let me finally answer the question.

So, why does this exception appear:

When you, having multiple spring-data modules within a project, try to create an interface for specific entity, that does not annotated with specific to persistence technology annotation (like @Entity in javax.persistence, or @Document in case of mongo, you name it), by extending the interface from spring-data-commons module (i.e. Repository or CrudRepository) - this will not work at all, becuase spring has basically no idea, to which exactly data storage you entity is assosiated. Is it MongoDb? or is it JPA? Or Cassandra? - it is impossible to determine in that way, see official doc. On the other hand, when there is only one spring data module in classpath - spring can conclude all by itself, becuase it is not ambiguous.

What can you do to solve it:

  1. Extend the techonogiy specific repository. For example, if you want entity A to be assosiated with PostgreSQL, then do not use CrudRepository - use JpaRepository. If you want entity B to be assosiated with Redis, the use RedisRepository and so on.

  2. Annotate your entity with annotation, that indicate it affiliation to the specific data storage. @Entity, @Document, @Table and so on.

I hope, this is clear now. I really did my best to explain it to you. Thanks for reading, have a nice day!

like image 16
misha2048 Avatar answered Oct 20 '22 20:10

misha2048


In one of projects, we had messages like:

Spring Data LDAP - Could not safely identify store assignment for repository candidate interface com.company.xxx.EncryptionKeyRepository.

Solution was to add this line into application.properties file

spring.data.ldap.repositories.enabled=false

This is for Spring Data LDAP. I guess it's similar for other Spring Data components.

like image 5
Igor Delac Avatar answered Oct 20 '22 18:10

Igor Delac