Currently I am getting an exception when deserializing a codestable typed class.
Imagine the following scenario:
public abstract class AbstractCodestableEntry implements java.io.Serializable {
private final String category;
private final String code;
protected AbstractCodestableEntry(final String category, final String code) {
this.category = category;
this.code = code;
}
// Getter for category and code
}
Here is one example of a concrete codestable class. Of this type we have ~100 classes (salutation, gender, workdays, ... and a lot of more functional related codestables)
public class SalutationCodestableEntry extends AbstractCodestableEntry {
public static final String KATEGORIE = "SALUTATION";
public static final SalutationCodestableEntry MR = new SalutationCodestableEntry ("1");
public static final SalutationCodestableEntry MRS = new SalutationCodestableEntry ("2");
...
private static final Map<String, SalutationCodestableEntry> BY_CODE = initCache();
private SalutationCodestableEntry(final String code) {
super(KATEGORIE, code);
}
private static Map<String, SalutationCodestableEntry> initCache() {
final SalutationCodestableEntry[] values = new SalutationCodestableEntry[] {MR, MRS, ...};
final Map<String, SalutationCodestableEntry> map = new HashMap<>();
for (final SalutationCodestableEntry e : values) {
map.put(e.getCode(), e);
}
return Collections.unmodifiableMap(map);
}
public static SalutationCodestableEntry valueOf(final String code) {
return BY_CODE.get(code);
}
}
When serializing an attribute of type SalutationCodestableEntry to JSON it looks like this
"org.company.SalutationCodestableEntry":{"category":"SALUTATION","code":"1"}
Currently when deserializing this I get the following exception:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.company.SalutationCodestableEntry` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: java.lang.Object[][0]->org.company.Dto["codestableEntry"])
I can adjust all the classes as I want, but actually
I already did some special serializing configurations for a few classes with Mixins. But that seems not to work here because of the inheritance (SalutationCodestableEntry extends AbstractCodestableEntry) and the use of a static method to return an object (SalutationCodestableEntry.valueOf(String code)
).
Currently my ObjectMapper configuration looks like this
@Bean(name = OBJECTMAPPER_QUALIFIER)
public ObjectMapper outboxObjectMapper() {
return new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
.registerModule(new JavaTimeModule())
.addMixIn(AnySpecialClass.class, AnySpecialClassMixin.class)
.addMixIn(...);
}
Is there any way to let Jackson know how to deserialize the codestable classes (like SalutationCodestableEntry)?
I asked this question on Jackson's GitHub: https://github.com/FasterXML/jackson/discussions/237
I solved this by adding the @JsonCreator annotation to all concrete codestable classes e.g.
@JsonCreator
public static SalutationCodestableEntry valueOf(final @JsonProperty("code") code) {
return BY_CODE.get(code);
}
As the codestable classes are generated and I am able to adjust the generator this seems to be the easiest solution for me in this case, even if I was looking for another centralized solution without modifying the concrete codestable classes.