husfuu / springboot-redis

redis implementations in springboot application
0 stars 0 forks source link

Error when creating beans, there is two beans with the same type `org.springframework.data.redis.core.RedisTemplate<?, ?>` #2

Open husfuu opened 1 year ago

husfuu commented 1 year ago

error message

Field template in com.springbootredis.repository.ProductDao required a single bean, but 2 were found:
 - redisTemplate: defined by method 'redisTemplate' in class path resource [com/springbootredis/config/RedisConfig.class]
 - stringRedisTemplate: defined by method 'stringRedisTemplate' in class path resource [org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.class]

This is because this line https://github.com/husfuu/springboot-redis/blob/6de40fd65d2adade1d34e0b4d9fbace966af8cbf/src/main/java/com/springbootredis/repository/ProductDao.java#L16

When I uncoment @Autowired code, the ProductDao confused which bean should inject, because there is two beans with the same type (org.springframework.data.redis.core.RedisTemplate<?, ?>)

husfuu commented 1 year ago

error message

Field template in com.springbootredis.repository.ProductDao required a single bean, but 2 were found:
 - redisTemplate: defined by method 'redisTemplate' in class path resource [com/springbootredis/config/RedisConfig.class]
 - stringRedisTemplate: defined by method 'stringRedisTemplate' in class path resource [org/springframework/boot/autoconfigure/data/redis/RedisAutoConfiguration.class]

To resolve this issue, you will need to provide a way for Spring to determine which bean to use. Here are a few options:

  1. Use @Qualifier to specify which bean to inject. You can annotate the template field in ProductDao with @Qualifier("redisTemplate") to specify that it should be injected with the redisTemplate bean.

  2. Remove one of the beans. If you are not using both redisTemplate and stringRedisTemplate in your application, you can remove the unused bean to resolve the conflict.

  3. Change the type of the template field. If you do not need to use any of the features provided by RedisTemplate, you can change the type of the template field to StringRedisTemplate, which will ensure that only the stringRedisTemplate bean is considered for injection.

I choose to implement option 1

@Repository
public class ProductDao {

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate<String, Object> template;

    // rest of the class implementation
}

In this example, I have added the @Qualifier("redisTemplate") annotation to the template field, which tells Spring to inject the redisTemplate bean into this field.

Note that the value passed to @Qualifier should match the name of the bean that you want to inject. In this case, we are injecting the redisTemplate bean, so we specify "redisTemplate" as the value of the @Qualifier annotation.