Suppose I have the following JPA entities:
@Entity
public class Inner {
@Id private Long id;
private String name;
// getters/setters
}
@Entity
public class Outer {
@Id private Long id;
private String name;
@ManyToOne private Inner inner;
// getters/setters
}
Both Spring and java EE have REST implementations with default serializers which will marshall the entities to/from JSON without further coding. But when converting Outer
to JSON, both Spring and EE nest a full copy of Inner
within it:
// Outer
{
"id": "1234",
"name": "MyOuterName",
"inner": {
"id": "4321",
"name": "MyInnerName"
}
}
This is correct behavior but problematic for my web services, since the object graphs can get deep/complex and can contain circular references. Is there any way to configure the supplied marshaller to marshall the POJOs/entities in a "shallow" way instead without having to create a custom JSON serializer for each one? One custom serializer that works on all entities would be fine. I'd ideally like something like this:
// Outer
{
"id": "1234",
"name": "MyOuterName",
"innerId": "4321"
}
I'd also like it to "unmarshall" the JSON back into the equivalent java object. Bonus kudos if the solution works with both Spring and java EE. Thanks!
NET objects as JSON (serialize) To write JSON to a string or to a file, call the JsonSerializer. Serialize method. The JSON output is minified (whitespace, indentation, and new-line characters are removed) by default.
Deserialization in the context of Gson means converting a JSON string to an equivalent Java object. In order to do the deserialization, we need a Gson object and call the function fromJson() and pass two parameters i.e. JSON string and expected java type after parsing is finished. Program output.
JSON-Java is a Java serialization/deserialization library. It parses JSON documents into Java objects and generates new JSON documents from the Java classes.
Note that Jackson does not use java. io. Serializable for anything: there is no real value for adding that. It gets ignored.
I had the same problem and ended up using jackson annotations on my Entities to control the serialization:
What you need is @JsonIdentityReference(alwaysAsId=true) to instruct the bean serializer that this reference should be only an ID. You can see an example on my repo:
https://github.com/sashokbg/company-rest-service/blob/master/src/main/java/bg/alexander/model/Order.java
@OneToMany(mappedBy="order", fetch=FetchType.EAGER)
@JsonIdentityReference(alwaysAsId=true) // otherwise first ref as POJO, others as id
private Set<OrderDetail> orderDetails;
If you want a full control of how your entities are represented as JSON, you can use JsonView to define which field is serialized related to your view.
@JsonView(Views.Public.class) public int id;
@JsonView(Views.Public.class)
public String itemName;
@JsonView(Views.Internal.class)
public String ownerName;
http://www.baeldung.com/jackson-json-view-annotation
Cheers !
After many problems I give reason to Cássio Mazzochi Molin saying that "the use of entities persistence in your REST API can not be a good idea"
I would do that the business layer transform persistence entities to DTO.
You can do this very easily with libraries like mapstruct
If you still want to continue with this bad practice you can use jackson and customize your jackson mapper
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With