Passing objects with class inheritance causes wrong deserialisation

Hi, TLDR we have implemented the following (the comments contain the reasoning). Maybe it was not necessary and there exists a more elegant solution.

 * Because Temporal stores data serialised without having access to the class definitions, it stores type
 * information based on the declared type. This applies to all types of methods: Workflows, Signals, Queries,
 * Activities. In case the objects passed are descendants of that type, this information is lost. Then during
 * deserialisation critical errors of type UnknownProperty will cause failure.
 * To overcome that problem we need to manually store the exact type and then deserialise to that type. To trick
 * the serialisation layer data is first transformed to a Tree which is generic and will be deserialised exactly,
 * and then we convert back to the right object by using the type information stored in a separate top-level
 * attribute.
public class WrappedPayload implements Serializable {
    static ObjectMapper MAPPER = new ObjectMapper(); // must be static

    static {
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        MAPPER.registerModule(new JavaTimeModule());

    String type;
    JsonNode data;

    public static WrappedPayload of(MessagePayload data) {
        return new WrappedPayload(

    public void replace(MessagePayload data) {
        if (!data.getClass().getTypeName().equals(type)) {
            throw new IllegalArgumentException("The type wrapped is immutable");
        } = MAPPER.valueToTree(data);

    public MessagePayload getData() {
        try {
            return (MessagePayload) MAPPER.treeToValue(data, Class.forName(type));
        } catch (ClassNotFoundException | JsonProcessingException e) {
            throw new RuntimeException(e);

    public String dataAsString() {
        return data.toString();