POSTing nested objects using spring data rest?
Asked Answered
R

1

16

I have recently started using spring-data-rest for my application. I have the following JPA entities:

@Entity
public class Super {
    @Id
    private long id;

    @JoinTable
    @OneToMany(cascade = CascadeType.ALL)
    private List<Child> children;
}

-----------------------------------------

@Entity
public class Super2 {
    @Id
    private long id;

    @JoinTable
    @OneToMany(cascade = CascadeType.ALL)
    private List<Child> children;
}

-----------------------------------------

@Entity
public class Child {
    @Id
    private long id;

    @Column
    private String childMetadata;
}

I can think of 2 methods of saving new instances of Super or Super2:

  1. Expose a @RestResource for Child class -> Create all the instances of Child before creating instances of Super or Super2 -> Pass the URLs of all the Child instances in payload of Super or Super2.
  2. Pass the details of Child in the payload of Super or Super2 without exposing @RestResource for Child class and the CascadeType.ALL will take care of creating Child instances.

There are some pros with both the methods:

  1. With option 1, I get an ability to add new Child objects to Super or Super2 just by POSTing the url of new Child to http://<server>:<port>/super/1/children. But I definitely loose the cascading functionality of database if I use this method.
  2. With option 2, I get all the cascading functionalities of database but I loose the flexibility of adding new Child instances.

Is there something I have totally missed? I want a way to use the cascading functionality of database without loosing the flexibility of adding new children on the fly.

Thanks for help. :)

Reider answered 25/7, 2016 at 14:32 Comment(1)
Personally I don't use spring-data-rest. In my experience, it works fairly well when reading data, as long as you only have one view (JSON representation) for each entity. Writing data however is often more complicated, since you have to manage relation and this often requires custom code. Also when you create entities from JSON deserialization, you have to know quite a bit about detached JPA entities, which most developers dont. Most developers would be better off writing separate DTOs for JSON views and writing service method to persist the data.Salmanazar
P
2

There is a third solution that should fit for you:

  1. Pass the details of Child in the payload of Super or Super2 without exposing @RestResource for the attribute 'children' of Super (and Super2).

You'll still can use /children, but you will be able to retrieve children with super and to post it!

To do this, just change your Super (and Super2) class like this:

public class Super {
    @Id
    @GeneratedValue
    private Long id;

    @JoinTable
    @OneToMany(cascade = CascadeType.ALL)
    @RestResource(exported=false)
    private List<Child> children;

    ...
}

Then you can POST on /supers:

{
    "children": [
        {
            "childMetadata": "inner"
        }
    ]
}
Pothunter answered 12/5, 2017 at 12:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.