I am building a RESTful service to view server relationships (A Server can contain another server as its parent). The service accepts JSON strings for CRUD commands.
I use @JsonIdentityInfo
and @JsonIdentityReference
in my Server Object, so that the user receives simplified JSON answers like this:
{"hostname":"childhostname", "parent":"parenthostname"}
As parent I only get the hostname of the parent and not a parent object - this is exactly what I want and works fine.
My problem begins when trying to de-serialize an update command (when trying to update the parent). If I send this:
curl -i -X POST -H 'Content-Type: application/json' -d '{"parent":"parenthostname"}' http://localhost:8080/myRestService/rest/servers/childhostname
Nothing happens - the parent will not be set. The problem lies in the delivered JSON string:
{"parent":"parenthostname"}
After debugging hibernate 2.4.4 source code, I found that my JSON string generates a com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Could not resolve Object Id [parenthostname]
. This Exception is not thrown but null will be returned.
When I remove @JsonIdentityInfo
and @JsonIdentityReference
, this JSON string just works fine and my parent will be updated (but then I lose my simplified answers and also get infinite loop problems).
So if I adjust my JSON string to this:
'{"parent":{"hostname":"parenthostname"}}'
The update works fine. But I would like to have the simplified (unwrapped) version working. Any ideas? I am thankful for any hint.
I am using Hibernate 4.2.4 and Jackson 2.4.4
This is my (simplified) Server class:
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="hostname")
public class Server extends A_Hardware {
@NaturalId
@Column(name="hostname", nullable=false, unique=true)
private String hostname = null;
@ManyToOne
@JsonIdentityReference(alwaysAsId = true)
private Server parent = null;
@OneToMany(fetch = FetchType.LAZY, mappedBy="parent")
@JsonIdentityReference(alwaysAsId = true)
private Set<Server> childServers = new HashSet<Server>();
[...]
// standard getters and setters
This is my RESTful service's update class:
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
@Path("{hostname}")
public Response update(@PathParam("hostname") final String hostname, JsonParser json){
Server s = null;
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
try{
s = mapper.readValue(json, Server.class);
This is my first question here, so please don't judge me too hard if my question might is not completely clear ;)
I kinda solved it with a workaround. To deliver and receive my desired, simplified JSON string, I now use
@JsonSetter
and@JsonProperty
.Also see this answer.