Redis hash serialization of nested Map<>

1,017 views
Skip to first unread message

Gadi Eichhorn

unread,
Sep 10, 2018, 9:32:48 AM9/10/18
to vert.x
Hi All,

I am trying to seralise a complex object to Redis as hash using HMSET
I have one property that is a map<ENUM, UUID> 

when I serialise the object to JsonObject I have the map serailsed to string and not to Json (String)
so I get this error when I try to desiralise the HASH from redis


java.lang.IllegalArgumentException: Cannot construct instance of `java.util.LinkedHashMap` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{current=12d13a9f-c5f3-4d5f-8052-8191a222d5cd}')
 at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: net.infraview.dcb.vendors.autointern.model.domain.MotorTurnDataImpl["terminals"])
at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3738)
at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3656)
at io.vertx.core.json.JsonObject.mapTo(JsonObject.java:99)

because the value of the map as string is not a json!

Ho do I serialise a POJO to JoonObject were any nested map is also serialised to a json string?

I can do the long way. Serialise to String and then back to JsonObject...

String json = Json.encode(mtd);
JsonObject obj = JsonObject.mapFrom(mtd);

but is there a shorter way, from POJO to JsonObject ?

thanks.

public class MotorTurnDataImpl {

private double duration;

private Map<TerminalType, UUID> terminals;
}

Tommaso Nolli

unread,
Sep 10, 2018, 1:02:51 PM9/10/18
to vert.x
I could have misunderstood your needs but what you call "the long way" is the correct way from what I can tell.
Java does not have a native JSON data type so you have t oconvert to/from strings:
Inserisci qui il codice...

String str = Json.encode(obj)
Clazz pojo = Json.decodeValue(str, clazz)

Tommaso

Gadi Eichhorn

unread,
Sep 11, 2018, 4:36:04 AM9/11/18
to vert.x
Thanks for that Tommaso,

How would you save this object above to Redis using HMSET? the API expect Map<String,Object> but by default the map is serialized to string and not to json. 

I tried to use some serialisation annotation like @JsonSerialize and @JsonDeserialise for the map property.

something like this?

//    @JsonDeserialize(keyUsing = TerminalKeyDeserializer.class)
// @JsonDeserialize(keyAs = TerminalType.class, contentAs = UUID.class)
    private Map<TerminalType, UUID> terminals;

Thanks,
G.

Charles Vuillecard

unread,
Sep 11, 2018, 7:08:11 AM9/11/18
to ve...@googlegroups.com
You can use jackson annotations to serialize your objects in json. Normally you can easily serialize a map to json. But if the objects of the map are not yours perhaps you’ll have a bit of work to make them serializable in json.

There are many tutorials and documentations about this on the web ;)

One random link after a research about this :
http://tutorials.jenkov.com/java-json/jackson-objectmapper.html#jackson-annotations

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/37278b86-aff6-420e-b1f8-abbd23b9c01c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gadi Eichhorn

unread,
Sep 11, 2018, 9:47:58 AM9/11/18
to vert.x
OK, thanks for all the help.

I had to make a custom Json Jackson serializer like so

@JsonSerialize(using= TerminalsSerializer.class)
@JsonDeserialize(using= TerminalsDeserializer.class)

private Map<TerminalType, UUID> terminals;


public class TerminalsSerializer extends JsonSerializer<Map<TerminalType, UUID>> {

@Override
public void serialize(Map<TerminalType, UUID> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(Json.encode(value));
}

}


@Slf4j
public class TerminalsDeserializer extends JsonDeserializer<Map<TerminalType, UUID>> {

@Override
public Map<TerminalType, UUID> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException{
log.debug("MAP: {}", p.getText());
return Json.decodeValue(p.getValueAsString(), Map.class);
}

}

Again, this is only because I am using the JsonObject.getMap for Redis HMSET. I think internally it uses toString() and the serialization to JSON breaks.

G.

Charles Vuillecard

unread,
Sep 11, 2018, 10:21:51 AM9/11/18
to ve...@googlegroups.com
Glad to see you resolved your issue :)

Reply all
Reply to author
Forward
0 new messages