web-dev-qa-db-ja.com

Spring Dataの@OneToManyサブリソースの関連付けのPOST REST

現在、Spring Data 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...
}

コメントJava:

@Entity
public class Comment {

    @Id
    @GeneratedValue
    private long id;
    private String author;
    private String content;

    @ManyToOne
    private Post post;

    // Standard getters and setters...
}

Spring Data 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);
    }
}

すべてが正常に機能しているようです。アプリケーションを実行すると、すべてが正常に動作しているように見えます。 POST新しいPostオブジェクトをhttp://localhost:8080/postsにできます:

本文:{"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"
        }
    }
}

ただし、http://localhost:8080/posts/1/commentsでGETを実行すると、空のオブジェクト{}が返され、同じURIにPOSTコメントをしようとすると、HTTP 405メソッドが取得されます禁じられている。

Commentリソースを作成し、このPostに関連付ける正しい方法は何ですか?可能な場合、http://localhost:8080/commentsに直接POSTすることは避けたいです。

100
ccampo

最初にコメントを投稿する必要があり、コメントの投稿中に関連付け投稿エンティティを作成できます。

以下のようになります。

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

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

そしてそれは完全に問題なく動作します。

48
Chetan Kokil

投稿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. 関連付けURIにPUTを発行して、コメントを投稿に割り当てます。

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

最後のステップでは、 text/uri-list の仕様に従って、改行で区切られたコメントを識別する複数のURIを送信して、一度に複数のコメントを割り当てることができます。

一般的な設計上の決定に関するいくつかのメモ。通常、投稿/コメントの例は、集計の優れた例です。つまり、CommentからPostへの逆参照を避け、CommentRepositoryも完全に避けます。コメントに独自のライフサイクルがない場合(通常は構成スタイルの関係ではありません)、コメントを直接インラインでレンダリングし、コメントを追加および削除するプロセス全体を使用することで対処できます JSONパッチ 。 Spring Data RESTは、今後のバージョン2.2の最新リリース候補に そのサポート を追加しました。

53
Oliver Drotbohm

マッピングの関連付けと構成には2つのタイプがあります。関連付けの場合、次のような結合テーブルの概念を使用しました

従業員--1からn->部門

したがって、Association Employee、Department、Employee_Departmentの場合、3つのテーブルが作成されます

コードでEmployeeRepositoryを作成するだけです。それとは別に、マッピングは次のようになります。

class EmployeeEntity{

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

   }

}

Depatment Entityには外部キーのマッピングが含まれないため、単一のjsonリクエストで部門を持つ従業員を追加するPOSTリクエストを試行すると、追加されます...

2
Naveen Goyal

同じシナリオに直面し、1対多のマッピングを使用し、メインエンティティ自体からデータをプルしたため、サブエンティティのリポジトリクラスを削除する必要がありました。今、私はデータで全体の応答を取得しています。

1
Selva

OneToManyマッピングの場合、マッピングするクラスのPOJOとそれに@OneToManyアノテーションを作成するだけで、内部的にはそのテーブルIDにマッピングされます。

また、データを取得するクラスにSerializableインターフェイスを実装する必要があります。

0
Sunny Chaurasia