Spring boot JPA - JSON without nested object with OneToMany relation

11,403

Solution 1

Yes, it is possible.

For this purpose you should use pair of Jackson annotations to your entity model:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true)
protected Location from;  

Your serialized JSON will look instead of this:

{
    "from": {
        "id": 3,
        "description": "New-York"
    } 
}

like this:

{
    "from": 3
}

As mentioned in official documentation:

@JsonIdentityReference - optional annotation that can be used for customizing details of a reference to Objects for which "Object Identity" is enabled (see JsonIdentityInfo)

alwaysAsId = true used as marker to indicate whether all referenced values are to be serialized as ids (true);

Note that if value of 'true' is used, deserialization may require additional contextual information, and possibly using a custom id resolver - the default handling may not be sufficient.

Solution 2

You can only ignore your JSON content using @JsonIgnore annotation. The field which you want to hide in your JSON at there you can annotate that with @JsonIgnore. You can change your JSON like this :

{
    "id": 0,
    "reservations": [
        {}
    ],
    "name": "string",
    "dateOfDeparture": "string",
    "distance": 0,
    "price": 0,
    "seats": 0,
    "from": {
        "id": 0
    },
    "to": {
        "id": 0
    }
}

But You can't like this:

{
    "id": 0,
    "reservations": [
        {}
    ],
    "name": "string",
    "dateOfDeparture": "string",
    "distance": 0,
    "price": 0,
    "seats": 0,
    "from": 0,
    "to": 1
}
Share:
11,403
Smajl
Author by

Smajl

Software developer with focus on Java and cloud technologies.

Updated on July 21, 2022

Comments

  • Smajl
    Smajl almost 2 years

    I have a project which deals with some ORM mapping of objects (there are some @OneToMany relations etc).

    I am using REST interface to treat these objects and Spring JPA to manage them in the API.

    This is an example of one of my POJOs:

    @Entity
    public class Flight {
    
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private long id;
      private String name;
      private String dateOfDeparture;
      private double distance;
      private double price;
      private int seats;
    
      @ManyToOne(fetch = FetchType.EAGER)
      private Destination fromDestination;
    
      @ManyToOne(fetch = FetchType.EAGER)
      private Destination toDestination;
    
      @OneToMany(fetch = FetchType.EAGER, mappedBy = "flight")
      private List<Reservation> reservations;
    }
    

    When making a request, I have to specify everything in the JSON:

    {
      "id": 0,
      "reservations": [
        {}
      ],
      "name": "string",
      "dateOfDeparture": "string",
      "distance": 0,
      "price": 0,
      "seats": 0,
      "from": {
        "id": 0,
        "name": "string"
      },
      "to": {
        "id": 0,
        "name": "string"
      }
    }
    

    What I would prefer, is actually specifying the id of referenced object instead of their whole bodies, like this:

    {
      "id": 0,
      "reservations": [
        {}
      ],
      "name": "string",
      "dateOfDeparture": "string",
      "distance": 0,
      "price": 0,
      "seats": 0,
      "from": 1,
      "to": 2
    }
    

    Is that even possible? Could someone give me some insight on how to do this? I am only finding tutorials on how to do the opposite (the solution I already have).

  • PhoneixS
    PhoneixS about 8 years
    I think the second part isn't true as show by the other answer.
  • kiedysktos
    kiedysktos about 7 years
    is @JsonIdentityInfo necessary here?
  • Johan
    Johan over 6 years
    I agree with @Amit khanduri
  • nayan dhabarde
    nayan dhabarde over 4 years
    This does not work if one request needs the nested data and other doesnt. Let's say I have a shop and an item. I want an item name of which I have and I want to retreive it with couple of shop details. Do you know a way to do that in spring boot?