Issue
I want to use both Redis and Mongo with repository manner (I do not want to use spring cache annotations but repository methods).
I annotate the main class with the following annotations.
@EnableMongoRepositories(basePackageClass = PersistencyRepository.class)
@EnableRedisRepositories(basePackageClass = CacheRepository.class)
@SpringBootApplication
Repos
public interface PersistencyRepository extends CrudRepository<Store, String> {}
public interface CacheRepository extends MongoRepository<Store, String> {}
Now, I am getting the following error.
The bean "cacheRepository" defined in com.repository.CacheRepository defined in @EnableMongoRepositories declared on StoreApplication, could not be registered. A bean with that name has already been defined in com.repository.CacheRepository defined in @EnableRedisRepositories declared on StoreApplication and overriding is disabled.
How can I use repos of differenet databases (mongo, redis)?
Solution
You extended the wrong repository interface (MongoRepository) on CacheRepository try extending CrudRepository instead.
Also, your mongo and redis entities should be separated to different packages, usually I just went with com.my.company.entity.mongo and com.my.company.entity.redis for each.
After that, you need to update those Configuration annotations. A better package design, instead of putting all annotations on Main is putting them on a separate package, then putting those annotations there. This has an added benefit of clearly splitting each configurations for what they actually do
for example:
package com.your.company.configuration;
import com.your.company.configuration.properties.ApplicationProperties;
import com.your.company.entity.mongo.BaseDocument;
import com.your.company.entity.postgres.BaseEntity;
import com.your.company.entity.redis.BaseHash;
import com.your.company.repository.mongo.BaseMongoRepository;
import com.your.company.repository.postgres.BaseJpaRepository;
import com.your.company.repository.redis.BaseRedisRepository;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableConfigurationProperties(ApplicationProperties.class)
@EnableJpaRepositories(basePackageClasses = {BaseEntity.class, BaseJpaRepository.class})
@EnableMongoRepositories(basePackageClasses = {BaseDocument.class,
BaseMongoRepository.class}, repositoryFactoryBeanClass = EnhancedMongoRepositoryFactoryBean.class)
@EnableRedisRepositories(basePackageClasses = {BaseHash.class, BaseRedisRepository.class})
public class BasicConfiguration {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
The above is only an example, usually I would split them further into one class each within the same package with names that describes what they are actually configuring, for example: MongoConfiguration.java, JpaConfiguration.java, etc. Note if you decide to go with that design, you need the @Configuration annotation in each of the separate classes
Answered By - Michael Chow
Answer Checked By - Marilyn (JavaFixing Volunteer)