34

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.

ROZZ
  • 1,334
  • 3
  • 20
  • 36
  • The Spring Boot Application will still component scan the hierarchy which is what I assume is causing the warnings. – Darren Forsythe Oct 29 '17 at 15:58
  • I have the same problem. I tried to exclude everything from everywhere, even from ComponentScan. Tried to specify everything explicitly, every repository is now JpaRepository to avoid confusion, each entity is javax.persistence.Entity, but I still get ~50 messages that Spring Data Redis is not sure about this and that repository. I'm trying everything for two hours now and cannot get it to work. – Dalibor Filus Feb 26 '18 at 14:59
  • 2
    Did you solve this issue? Same problem without redis. – chomp Apr 18 '18 at 15:21
  • i have same problem with spring boot 2.0.2.RELEASE, spring-boot-starter-data-jpa:2.0.2.RELEASE and spring-data-elasticsearch:3.0.7.RELEASE; EnableJpaRepositories and @EnableElasticsearchRepositories are not working – davey Jun 12 '18 at 02:59
  • What is the solution to solve this problem? I'm working on JPA and Spring-boot redis and data are saving in MySql not in redis, please help – nitinsridar Dec 29 '18 at 08:01

7 Answers7

28

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!

Mikhail2048
  • 1,715
  • 1
  • 9
  • 26
  • thanks for your explanation. could you please have a look at this question :https://stackoverflow.com/questions/72669715/how-to-avoid-conflit-between-reactivecrudrepository-and-reactivemongorepository im facing the same waring and there is no way to replace ReactiveCrudRepository by something like JpaReactiveRepository – James Jun 19 '22 at 11:23
  • I think the author is not asking why his repositories can't detect associated repositories. – I have 10 fingers Jan 17 '23 at 06:14
  • Actually his repositories can be detected its associated tech. The problem is `spring-data-redis` produces unexpected logs which is it doesn't know which repositories shouldn't be redis repository even he specified which classes under given packages should be handled as its associated tech. – I have 10 fingers Jan 17 '23 at 06:20
  • What an enlightenment! I had R2DBC and Reactive Mongo deps and my Repository bean was not scanned. I drilled down to the issue of redis and r2dbc data dep co-existence and this reminded the basics! Thanks. – Karthik R Mar 18 '23 at 17:02
  • Key point is to use `extends JpaRepository` for all your DB repositories instead of `extends CrudRepository` – raghavsood33 May 29 '23 at 14:41
19

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

Nikhil
  • 1,126
  • 12
  • 26
8

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 {

}
Hank
  • 1,318
  • 10
  • 29
5

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.

Igor Delac
  • 175
  • 2
  • 9
0

Probably it's too late, but anyway. It's just an informational messages that helps you understand how Spring Data Modules are configured. For example:

 INFO 87518 --- [main] .RepositoryConfigurationExtensionSupport : 
     Spring Data JPA - Could not safely identify store assignment for repository 
          candidate interface com.some.package.MyRepository.

Means that Spring Data JPA module will skip MyRepository class and will not be using it.

Alex
  • 1,986
  • 22
  • 23
  • 1
    What is the solution to solve this problem? I'm working on JPA and Spring-boot redis and data are saving in MySql not in redis, please help – nitinsridar Dec 29 '18 at 08:01
0

this worked like a charm for me, I'm using two Datasources Mysql and MongoDb

@EnableJpaRepositories(basePackages = "com.repository.MysqlRepository") @EnableMongoRepositories(basePackages = "com.repository.MongoRepository")

0

In my case, I am using Redis, so addded @RedisHash to the entity class to distinguish certain repositories. enter image description here

Gaganam Krishna
  • 121
  • 1
  • 4