I have a JSON structure which contains maps of strings to object:
{
"domains": {
"ldap": {
"users": {
"fwalther": {
"firstName": "Fritz",
"lastName": "Walther"
},
// ...
}
}
},
// ...
}
I want to deserialize this structure to Domain
and User
objects using Jackson, and I want from each user have a back-reference to it's map key (which is the user ID) and to the Domain
container. Either of this works, but it fails if I try to get both back-references at once.
Java classes with @JsonManagedReference
and @JsonBackReference
:
public class Domain {
@JsonManagedReference
@JsonDeserialize(contentUsing = UserDeserializer.class)
private Map<String, User> users;
public Map<String, User> getUsers() {
return users;
}
}
public class User {
@JsonBackReference
private Domain domain;
String userId;
private String firstName;
private String lastName;
// ... getters
}
Custom deserializer to get the map key:
public class UserDeserializer extends JsonDeserializer<User> {
@Override
public User deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
String key = p.getCurrentName();
User result = p.readValueAs(User.class);
result.userId = key;
return result;
}
}
Both mechanisms, i.e. the @JsonManagedReference
/@JsonBackReference
pair and @JsonDeserialize
with the custom deserializer, work if I activate only one of them. But if I combine the mechanisms (as shown in the code above), I get the following exception when parsing the JSON:
java.lang.IllegalArgumentException: Cannot handle managed/back reference 'defaultReference': type: value deserializer of type org.example.UserDeserializer does not support them
at com.fasterxml.jackson.databind.JsonDeserializer.findBackReference(JsonDeserializer.java:366) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.deser.std.ContainerDeserializerBase.findBackReference(ContainerDeserializerBase.java:104) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase._resolveManagedReferenceProperty(BeanDeserializerBase.java:786) ~[jackson-databind-2.9.8.jar:2.9.8]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:487) ~[jackson-databind-2.9.8.jar:2.9.8]
...
Looking at the code where the exception is thrown, I see that I'd need to implement the findBackReference
in my custom deserializer, but I have no clue how, and I couldn't find and information on this either. Any ideas?
Or are there other ways to get both the map key and back reference to the containing object?