[java] SpringData REST에서 @OneToMany 하위 리소스 연관 게시

현재 SpringData REST를 사용하는 Spring Boot 애플리케이션이 있습니다. 다른 도메인 엔터티와 관계 가있는 도메인 엔터티 Post가 있습니다 . 이러한 클래스는 다음과 같이 구성됩니다.@OneToManyComment

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"
        }
    }
}

그러나 GET을 수행 http://localhost:8080/posts/1/comments하면 빈 개체가 {}반환되고 동일한 URI에 주석을 게시하려고하면 HTTP 405 Method Not Allowed가 표시됩니다.

Comment자원 을 만들고 이것과 연결 하는 올바른 방법은 무엇입니까 Post? http://localhost:8080/comments가능한 경우 직접 게시하는 것을 피하고 싶습니다 .



답변

먼저 댓글을 게시해야하며 댓글을 게시하는 동안 연관 게시물 엔티티를 만들 수 있습니다.

다음과 같이 보일 것입니다.

http://{server:port}/comment METHOD:POST

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

완벽하게 잘 작동합니다.


답변

이미 post URI 및 연관 자원의 URI를 발견했다고 가정하면 ( $association_uri다음에 있는 것으로 간주 ) 일반적으로 다음 단계를 수행합니다.

  1. 댓글을 관리하는 컬렉션 리소스를 확인하세요.

    curl -X GET http://localhost:8080
    
    200 OK
    { _links : {
        comments : { href : "…" },
        posts :  { href : "…" }
      }
    }
  2. 리소스에 대한 comments링크와 POST데이터를 따르십시오 .

    curl -X POST -H "Content-Type: application/json" $url
    {  // your payload // … }
    
    201 Created
    Location: $comment_url
  3. PUT연관 URI에 a 를 발행하여 게시물에 댓글을 지정하십시오 .

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

마지막 단계에서의 사양에 따라 text/uri-list주석을 식별하는 여러 URI를 줄 바꿈으로 구분하여 제출하여 한 번에 여러 주석을 할당 할 수 있습니다.

일반적인 디자인 결정에 대한 몇 가지 추가 정보. 게시물 / 댓글 예는 일반적으로 난에서 백 참조를 피할 것 수단 집계에 대한 좋은 예입니다 Comment받는 사람 Post또한 피 CommentRepository를 완전히합니다. 주석에 자체 수명주기가없는 경우 (일반적으로 구성 스타일 관계가 아님) 주석을 직접 인라인으로 렌더링하고 주석을 추가하고 제거하는 전체 프로세스를 다음을 사용하여 처리 할 수 ​​있습니다. JSON 패치 . SpringData REST는 향후 버전 2.2의 최신 릴리스 후보에서 이에 대한 지원을 추가했습니다 .


답변

매핑 연결 및 구성에는 두 가지 유형이 있습니다. 연관의 경우 조인 테이블 개념을 다음과 같이 사용했습니다.

직원 –1에서 n-> 부서

따라서 Association Employee, Department, Employee_Department의 경우 3 개의 테이블이 생성됩니다.

코드에서 EmployeeRepository를 생성하기 만하면됩니다. 그 매핑을 제외하고는 다음과 같아야합니다.

class EmployeeEntity{

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

   }

}

Depatment Entity는 forign 키에 대한 매핑을 포함하지 않으므로 이제 단일 json 요청에서 Department와 Employee를 추가하기위한 POST 요청을 시도하면 추가됩니다 ….


답변

나는 동일한 시나리오에 직면했고 일대 다 매핑을 사용하고 주 엔티티 자체를 통해 데이터를 가져 왔기 때문에 하위 엔티티에 대한 저장소 클래스를 제거해야했습니다. 이제 데이터로 전체 응답을 받고 있습니다.


답변

oneToMany 매핑의 경우 매핑하려는 해당 클래스에 대한 POJO와 @OneToMany 주석을 작성하면 내부적으로 해당 테이블 ID에 매핑됩니다.

또한 데이터를 검색하는 클래스에 Serializable 인터페이스를 구현해야합니다.


답변