Search code examples
spring-bootredisspring-data-redisredisson

When I use CompositeCodec(StringCodec.INSTANCE,new TypedJsonJacksonCodec(Member.class))how can RMap get value be correctly converted to a Java object?


Line 55 expects map.get(name) to return a value of type Member instead of LinkedHashMap, When using CompositeCodec Specify mapValueCodec as TypedJsonJacksonCodec.

The getMemberByName method will throw the following exception enter image description here

Ifdon't specify CompositeCodec but use JsonJacksonCodec then it works fine.

When I use new CompositeCodec(StringCodec.INSTANCE, new TypedJsonJacksonCodec(Member.class));how can the RMap get value be correctly converted to a Java object?

package org.redisson.example.collections;

import lombok.Getter;
import lombok.Setter;
import org.redisson.Redisson;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.redisson.codec.CompositeCodec;
import org.redisson.codec.TypedJsonJacksonCodec;
import org.redisson.config.Config;

import java.util.List;


public class RMapErrorDemo {
    static final String MemberKey = "members";
    static final CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, new TypedJsonJacksonCodec(Member.class));


    public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://127.0.0.1:6379");
        RedissonClient redissonClient = Redisson.create(config);

        // create members
        List<Member> members = List.of(
                new Member("张三", "zhangsan", List.of(new Department("1", "技朧部"))),
                new Member("李四", "lisi", List.of(new Department("2", "产品部"))),
                new Member("王五", "wangwu", List.of(new Department("3", "市场部"))),
                new Member("赵六", "zhaoliu", List.of(new Department("4", "运营部"))),
                new Member("孙七", "sunqi", List.of(new Department("5", "财务部")))
        );

        saveMember2Redis(redissonClient, members);

        // get member
        Member member = getMemberByName(redissonClient, "张三");

    }


    public static void saveMember2Redis(RedissonClient redissonClient, List<Member> members) {
        RMap<String, Member> map = redissonClient.getMap(MemberKey, codec);
        for (Member member : members) {
            map.put(member.getName(), member);
        }
    }

    public static Member getMemberByName(RedissonClient redissonClient, String name) {

        RMap<String, Member> map = redissonClient.getMap(MemberKey, codec);

        return map.get(name);
    }
}


@Getter
@Setter
class Member {
    private String name;

    private String alias_name;

    private List<Department> depts;

    public Member(String name, String aliaName, List<Department> depts) {
        this.name = name;
        this.alias_name = aliaName;
        this.depts =  depts;
    }
}

@Getter
@Setter
class Department {
    private String id;

    private String name;

    public Department(String number, String s) {
        this.id = number;
        this.name = s;
    }
}

Solution

  • Sounds like the codec used for serialization and deserialization are not matching. Try:

    static final CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, 
        new TypedJsonJacksonCodec(String.class, Member.class));
    

    If that fails try with JsonJacksonCodec:

    static final CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, 
        new JsonJacksonCodec());