POSTing combining @ OneToMany-sub-resources in Spring Data REST

I currently have a Spring boot application using Spring Data REST. I have a Post domain object that has @OneToMany related to another domain object, Comment . These classes are structured as follows:

Post.java:

 @Entity public class Post { @Id @GeneratedValue private long id; private String author; private String content; private String title; @OneToMany private List<Comment> comments; // Standard getters and setters... } 

Comment.java:

 @Entity public class Comment { @Id @GeneratedValue private long id; private String author; private String content; @ManyToOne private Post post; // Standard getters and setters... } 

Their Spring Data REST JPA repositories are the base implementations of CrudRepository :

PostRepository.java:

 public interface PostRepository extends CrudRepository<Post, Long> { } 

CommentRepository.java:

 public interface CommentRepository extends CrudRepository<Comment, Long> { } 

The application entry point is a standard, simple Spring boot application. Everything is set up for stock.

Application.java

 @Configuration @EnableJpaRepositories @Import(RepositoryRestMvcConfiguration.class) @EnableAutoConfiguration public class Application { public static void main(final String[] args) { SpringApplication.run(Application.class, args); } } 

Everything is working correctly. When I run the application, everything works correctly. I can send POST a new Post object to http://localhost:8080/posts as follows:

Body: {"author":"testAuthor", "title":"test", "content":"hello world"}

Result http://localhost:8080/posts/1 :

 { "author": "testAuthor", "content": "hello world", "title": "test", "_links": { "self": { "href": "http://localhost:8080/posts/1" }, "comments": { "href": "http://localhost:8080/posts/1/comments" } } } 

However, when I do a GET at http://localhost:8080/posts/1/comments , I return an empty {} object, and if I try to send a POST message to the same URI, I get an HTTP 405 method that is not allowed.

What is the correct way to create a Comment resource and associate it with this Post ? I would like to avoid POSTing directly http://localhost:8080/comments , if possible.

+84
java spring spring-boot spring-data-jpa spring-data-rest
Aug 14 '14 at 15:32
source share
4 answers

You must post a comment first, and while posting a comment, you can create an association message object.

It should look something like this:

 http://{server:port}/comment METHOD:POST {"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"} 

and it will work perfectly.

+34
Oct 17 '14 at 2:09
source share

Assuming that you have already discovered the message URI and therefore the association resource URI (which is considered $association_uri in the following), it usually does the following:

  • Open the collection resource management report:

     curl -X GET http://localhost:8080 200 OK { _links : { comments : { href : "…" }, posts : { href : "…" } } } 
  • Follow the comments link and POST your data to the resource:

     curl -X POST -H "Content-Type: application/json" $url { … // your payload // … } 201 Created Location: $comment_url 
  • Assign a comment to the message by sending a PUT to the association URI.

     curl -X PUT -H "Content-Type: text/uri-list" $association_url $comment_url 204 No Content 

Please note that in the last step, according to the text/uri-list specification, you can send several URIs identifying comments separated by a break line to assign multiple comments at the same time.

A few notes on general design decisions. The post / comments example is usually a great example for the aggregate, which means that I would avoid link CommentRepository from Comment to POST , and also completely avoid CommentRepository . If comments do not have a life cycle per se (which usually are not related to compositional style), you are more likely to get comments displayed directly in the line, and the whole process of adding and removing comments can be examined using the JSON Patch . Spring Data REST has added support for this in the latest release for the upcoming version 2.2.

+46
Aug 22 '14 at 16:31
source share

I came across the same scenario, and I had to remove the repository class for the subobject, since I used one-many matching and pulling data through the main entity. Now I get the whole answer with the data.

+1
Jun 14 '16 at 20:54 on
source share

There are 2 types of mapping Association and Composition. In the case of association, we used the concept of joining a table, for example

Employee - 1 to n-> Department

Thus, 3 tables will be created in the case of the Association Employee, Department, Employee_Department

You only need to create an EmployeeRepository in your code. In addition to this display, it should be like this:

 class EmployeeEntity{ @OnetoMany(CascadeType.ALL) private List<Department> depts { } } 

Depatment Entity will not contain mappping for forign key ... so now when you try the POST request to add Employee with Department to one json request, then it will be added ....

+1
Jun 27 '17 at 19:03
source share



All Articles