Redisson and Json for objects

11.5k views Asked by At

I currently trying out Redisson as a Redis client and so far I've been able to replace a good chunk of code with no issues. The only problem I'm having now is trying to use the distributed collections, such as Queue or List.

List<MyEntry> entries = // read some sample data from a file
RedissonClient client = // create client
RBlockingQueue<MyEntry> queue = client.getBlockingQueue("test-queue", new JsonJacksonCodec());

queue.addAll(entries);
List<MyEntry> readBack = new ArrayList<>();
queue.drainTo(readBack);

When I get to the last line, I always get this exception -

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' at [Source: (io.netty.buffer.ByteBufInputStream); line: 1, column: 1439]

When I add @JsonTypeInfo to my class, it appears to work, however, most of the classes I don't have access to add the @JsonTypeInfo annotation to.

I am missing something here? One way to work around this could be to use the ByteArrayCodec and serialize/deserialize using my own ObjectMapper (edit: trying this throws another type of exception!), but if possible I'd prefer to let Redisson handle this since it offers many codecs already.

Any help is much appreciated as usual!

A bit more info - I ended up writing my own simple Codec, that simply takes a Class as a parameter, and creates a Decoder and Encoder works similiar to how the JsonJacksonCodec works, with one difference -

 private static class MyCodec<T> implements Codec {

    private final Decoder<Object> decoder = new Decoder<Object>() {
        @Override
        public T decode(ByteBuf buf, State state) throws IOException {
            return mapper.readValue((InputStream) new ByteBufInputStream(buf), type);
        }
    };

    private final ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
    private final Class<T> type;

    public MyCodec(Class<T> type) {
        this.type = type;
    }

    // rest of methods...
}

And I was able to get my example working - but this feels like a workaround, rather than a solution to the original problem, and I don't want to have to write additional Codecs for each implementation I have :)

2

There are 2 answers

0
Redisson_RuiGu On BEST ANSWER

Redisson provides a default Jackson codec for classes that are NOT annotated with Jackson annotations. Your existing annotations is taking precedence over the default codec setting, hence the problem. You can try other types of codec like fst codec or supply your own compatible object mappper to the Jackson codec.

0
DALDEI On

See Fundamental API design flaw -- with respect to encoding and serialization

I would very much like to be wrong. Currently looking for a way to address this that doesn't require major surgery.