原创

RedisTemplate list leftPushAll不生效问题排查

RedisConfig配置

@Configuration

@EnableCaching

public class RedisConfig extends CachingConfigurerSupport {

    @Bean

    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

        RedisTemplate<String, Object> template = new RedisTemplate<>();

        template.setConnectionFactory(factory);

        GenericFastJsonRedisSerializer serializer = new GenericFastJsonRedisSerializer();

        template.setDefaultSerializer(serializer);

        template.setValueSerializer(serializer);

        return template;

    }
...
}

Service中接收RedisTemplate

@Resource   
private RedisTemplate<String, HostMetric> redisTemplate;

存储

redisTemplate.opsForList().leftPushAll(CPU_RISK_LIST, list);

结果,存储为一条数据。

最早的解决方法

参考网络相关文章

解决redisTemplate中leftPushAll隐性bug的问题Java教程服务器之家

http://www.zzvips.com/article/182199.html

添加toArray()

redisTemplate.opsForList().leftPushAll(CPU_RISK_LIST, list.toArray());

结果,成功。

刨根问底

猜测和泛型传递有关,写测试case

一级泛型传递

public class TestOverload {

    public static void main(String[] args) {

        //overload正常

//        Container<Object> container=new Container<Object>();

        Container container=new Container();

        List list = new ArrayList<>();

        list.add("haha");

        container.add(list);

    }

}
public class Container<V> {

    private List<V> list;



    public void add(V... values) {

        System.out.println("add 1");

    }



    public void add(Collection<V> values) {

        System.out.println("add 2");



    }

}

结果,overload没有问题

二级泛型传递

public class TestOverload2 {

    public static void main(String[] args) {

        //此情况下,会导致overload失败

        Container2<Object> container = new Container2<>();

//        Container2 container=new Container2<>();

//        Container2<String> container=new Container2<>();



        List<String> list = new ArrayList<>();

        list.add("haha");

        container.operation().add(list);

        container.operation().add("list");

    }

}
public class Container2<V> {

    private Operation<V> operation;



    public Operation<V> operation() {

        return this.operation;

    }



}
public class Operation<V> {



    public void add(V... values) {

        System.out.println("add 1");

    }



    public void add(Collection<V> values) {

        System.out.println("add 2");



    }

}

结果:泛型传递Object的情况下,overload失败

优化解决思路

修改 RedisTemplate

@Resource

private RedisTemplate redisTemplate;

结果,成功

猜测

多级泛型传递,如果泛型用Object,可能导致overload失效

正文到此结束