SpringData REST에서 @OneToMany 하위 리소스 연관 게시
현재 SpringData REST를 사용하는 Spring Boot 애플리케이션이 있습니다. 다른 도메인 엔터티와 관계 가있는 도메인 엔터티 Post
가 있습니다 . 이러한 클래스는 다음과 같이 구성됩니다.@OneToMany
Comment
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...
}
SpringData REST JPA 저장소는 다음의 기본 구현입니다 CrudRepository
.
PostRepository.java :
public interface PostRepository extends CrudRepository<Post, Long> { }
CommentRepository.java :
public interface CommentRepository extends CrudRepository<Comment, Long> { }
애플리케이션 진입 점은 표준의 간단한 Spring Boot 애플리케이션입니다. 모든 것이 구성 재고입니다.
Application.java
@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
모든 것이 올바르게 작동하는 것 같습니다. 응용 프로그램을 실행하면 모든 것이 올바르게 작동하는 것처럼 보입니다. 다음 http://localhost:8080/posts
과 같이 새 Post 객체를 게시 할 수 있습니다 .
몸: {"author":"testAuthor", "title":"test", "content":"hello world"}
결과 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 perform a GET at http://localhost:8080/posts/1/comments
I get an empty object {}
returned, and if I try to POST a comment to the same URI, I get an HTTP 405 Method Not Allowed.
What is the correct way to create a Comment
resource and associate it with this Post
? I'd like to avoid POSTing directly to http://localhost:8080/comments
if possible.
You have to post the comment first and while posting the comment you can create an association posts entity.
It should look something like below :
http://{server:port}/comment METHOD:POST
{"author":"abc","content":"PQROHSFHFSHOFSHOSF", "post":"http://{server:port}/post/1"}
and it will work perfectly fine.
Assuming you already have discovered the post URI and thus the URI of the association resource (considered to be $association_uri
in the following), it generally takes these steps:
Discover the collection resource managing comments:
curl -X GET http://localhost:8080 200 OK { _links : { comments : { href : "…" }, posts : { href : "…" } } }
Follow the
comments
link andPOST
your data to the resource:curl -X POST -H "Content-Type: application/json" $url { … // your payload // … } 201 Created Location: $comment_url
Assign the comment to the post by issuing a
PUT
to the association URI.curl -X PUT -H "Content-Type: text/uri-list" $association_url $comment_url 204 No Content
Note, that in the last step, according to the specification of text/uri-list
, you can submit multiple URIs identifying comments separated by a line break to assign multiple comments at once.
A few more notes on the general design decisions. A post/comments example is usually a great example for an aggregate, which means I'd avoid the back-reference from the Comment
to the Post
and also avoid the CommentRepository
completely. If the comments don't have a lifecycle on their own (which they usually don't in an composition-style relationship) you rather get the comments rendered inline directly and the entire process of adding and removing comments can rather be dealt with by using JSON Patch. Spring Data REST has added support for that in the latest release candidate for the upcoming version 2.2.
There are 2 types of mapping Association and Composition. In case of association we used join table concept like
Employee--1 to n-> Department
So 3 tables will be created in case of Association Employee, Department, Employee_Department
You only need to create the EmployeeRepository in you code. Apart from that mapping should be like that:
class EmployeeEntity{
@OnetoMany(CascadeType.ALL)
private List<Department> depts {
}
}
Depatment Entity will not contain any mappping for forign key...so now when you will try the POST request for adding Employee with Department in single json request then it will be added....
I faced the same scenario and I had to remove the repository class for the sub entity as I have used one to many mapping and pull data thru the main entity itself. Now I am getting the entire response with data.
For oneToMany mapping, just make a POJO for that class you want to Map, and @OneToMany annotation to it, and internally it will map it to that Table id.
Also, you need to implement the Serializable interface to the class you are retrieving the Data.
'developer tip' 카테고리의 다른 글
다른 div의 아래쪽 근처에 div 배치 (0) | 2020.08.18 |
---|---|
표시가 테이블 셀로 설정된 요소의 경우 Colspan / Rowspan (0) | 2020.08.18 |
JsonP에 데이터 게시 (0) | 2020.08.18 |
NoSql 단기 집중 과정 / 튜토리얼 (0) | 2020.08.18 |
URL / 주소 표시 줄에서 자바 스크립트 함수 호출 (0) | 2020.08.18 |