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.
You can only have one repository per entity... however, you can have multiple entities per table; thus, having multiple repositories per table.
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 .
Spring Data Jpa provides EnableJpaRepositories annotation which is used to scan the packages for configuration and repository class for Spring Data JPA.
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
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 {
}
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:
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:
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.
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With