How to serialize only the ID of a child with Jackson
You can write a custom serializer like this:
public class ChildAsIdOnlySerializer extends StdSerializer<Child> {
// must have empty constructor
public ChildAsIdOnlySerializer() {
this(null);
}
public ChildAsIdOnlySerializer(Class<Child> t) {
super(t);
}
@Override
public void serialize(Child value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
gen.writeString(value.id);
}
Then use it by annotating the field with @JsonSerialize
:
public class Parent {
@JsonSerialize(using = ChildAsIdOnlySerializer.class)
public Child child;
}
public class Child {
public int id;
}
There are couple of ways. First one is to use @JsonIgnoreProperties
to remove properties from a child, like so:
public class Parent {
@JsonIgnoreProperties({"name", "description" }) // leave "id" and whatever child has
public Child child; // or use for getter or setter
}
another possibility, if Child object is always serialized as id:
public class Child {
// use value of this property _instead_ of object
@JsonValue
public int id;
}
and one more approach is to use @JsonIdentityInfo
public class Parent {
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@JsonIdentityReference(alwaysAsId=true) // otherwise first ref as POJO, others as id
public Child child; // or use for getter or setter
// if using 'PropertyGenerator', need to have id as property -- not the only choice
public int id;
}
which would also work for serialization, and ignore properties other than id. Result would not be wrapped as Object however.
Given for example a simple company with employees structure, in combination with
@JsonIgnore
@ManyToOne(cascade = {CascadeType.REFRESH, CascadeType.DETACH})
@JoinColumn(name = "child_id")
I would suggest to add the following:
@JsonProperty("child_id")
for sending the child_id as property without it you won't get anything on client side, and-
@JsonIgnoreProperties
It will give the option to copy and paste the Json received from the server and send it back for example to update it. Without it you will get an exception when sending back, Or you will have to remove the child_id property from the received Json.
public class Company {
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
private List<Employee> employees;
}
@JsonIgnoreProperties(value = {"company_id"},allowGetters = true)
public class Employee{
@JsonIgnore
@ManyToOne(cascade = {CascadeType.REFRESH, CascadeType.DETACH})
@JoinColumn(name = "company_id")
public Company company
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class,
property="id")
@JsonIdentityReference(alwaysAsId=true)
@JsonProperty("company_id")
}
public Company getCompany() {
return company;
}
}