I’m creating 2 RespositoryConfigs with @EnableRedisRepositories and different RedisTemplate/redisTemplateRef references, however, it is always using only 1 DB.
Here some example (skipping the templates config which are using different RedisConnectionFactory and different RedisClient), and each package have only 1 repository A.class or B.class.
@Configuration
@EnableRedisRepositories(
basePackages = "com.X.A",
includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = A.class),
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = B.class),
redisTemplateRef = "templateA"
)
public class ARepositoryRedisConfig {
}
and
@EnableRedisRepositories(
basePackages = "com.X.B",
includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = B.class),
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = A.class),
redisTemplateRef = "templateB"
)
public class BRepositoryRedisConfig {
}
The repositories are CrudRepository.
Going a bit deeper, I see on registering the beans in:
org.springframework.data.redis.repository.configuration.RedisRepositoryConfigurationExtension#registerBeansForRoot
When registering the second repository I see it skips on: registerIfNotAlreadyRegistered because the first template is already registered.
Looking at other Spring-Data repository configs, it supposed to be supported.
Edit 1: How templates are configured
@Bean
public RedissonClient ARedissonClient(
@Value("${A.redis.host}") String host,
@Value("${A.redis.port}") String port,
@Value("${diagnostic.app.name}") String appName,
@Value("${redis.connectionPoolSize}") int connectionPoolSize,
@Value("${redis.minimumIdleSize}") int connectionMinimumIdleSize,
@Value("${redis.retryAttempts}") int retryAttempts,
@Value("${redis.retryInterval}") int retryInterval,
@Value("${A.redis.password:}") String password,
@Value("${redis.timeout:6000}") int timeout,
@Value("${redis.dns.monitoring.interval:5000}") int dnsMonitoringInterval
) {
...
}
@Bean
public RedisConnectionFactory ARedisConnectionFactory(RedissonClient ARedissonClient) {
return new RedissonConnectionFactory(ARedissonClient);
}
@Bean(name = "templateA")
public RedisTemplate<String, String> templateA(RedisConnectionFactory ARedisConnectionFactory) {
...
}
And another one with templateB and different B.redis.host.
I tested calling the templates directly and both setups are fine, they are just not binding to the repositories, only 1 template is used for all repositories regardless what multiple EnableRedisRepositories defines.
3
Answers
With great help from Redis support,they pointed it requires configuring and wiring keyValueTemplateRef as well, besides only redisTemplateRef.
So, configuration should look like:
And same for BRepositoryRedisConfig and teamplateB.
Make sure that the data source configuration for the two databases have different property namespace.
Also if you have specified them in a properties file other than the application.properties make sure that you add
@PropertySource
annotation as well above your configuration class.On a different note, I think you do not have to add the include and exclude filters as the classes are in different packages.
I have such a sample with connecting 2 Redis to a single Spring application (with default Lettuce), it shows which beans and bean ref need to be wired.
https://github.com/alexvasseur/spring-twored