首页 文章

在Spring Data REST中发布@OneToMany子资源关联

提问于
浏览
90

目前我有一个使用Spring Data REST的Spring Boot应用程序 . 我有一个域实体 Post ,它与另一个域实体 @OneToMany 具有 @OneToMany 关系 . 这些类的结构如下:

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

他们的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时,我得到一个空对象 {} 返回,如果我尝试将注释POST到同一个URI,我得到一个HTTP 405方法不允许 .

创建 Comment 资源并将其与此 Post 关联的正确方法是什么?如果可能的话,我想避免直接POST到 http://localhost:8080/comments .

5 回答

  • 2

    您必须先发布评论,在发布评论时,您可以创建一个关联发布实体 .

    它应该如下所示:

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

    它会完美地运作 .

  • 0

    假设您已经发现了post URI,从而发现了关联资源的URI(以下被认为是 $association_uri ),它通常采取以下步骤:

    • 发现管理评论的馆藏资源:
    curl -X GET http://localhost:8080
    
    200 OK
    { _links : {
        comments : { href : "…" },
        posts :  { href : "…" }
      }
    }
    
    • 按照 comments 链接和 POST 您的数据到资源:
    curl -X POST -H "Content-Type: application/json" $url 
    { … // your payload // … }
    
    201 Created
    Location: $comment_url
    
    • 通过向关联URI发出 PUT 将评论分配给帖子 .
    curl -X PUT -H "Content-Type: text/uri-list" $association_url
    $comment_url
    
    204 No Content
    

    请注意,在最后一步中,根据text/uri-list的规范,您可以提交多个URI,用于标识由换行符分隔的注释,以便一次分配多个注释 .

    关于一般设计决策的一些注释 . post / comments示例通常是聚合的一个很好的例子,这意味着我将避免从 CommentPost 的反向引用,并完全避免 CommentRepository . 如果评论不是在组合风格的关系中,那么您宁可直接内联呈现注释,而是可以使用JSON Patch来处理添加和删除注释的整个过程 . Spring Data REST在即将发布的2.2版本的最新候选版本中添加了support for that .

  • 40

    映射关联和组合有两种类型 . 在关联的情况下,我们使用连接表概念

    员工 - 1到n->部门

    因此,如果是Association Employee,Department,Employee_Department,将创建3个表

    您只需要在代码中创建EmployeeRepository . 除了映射应该是这样的:

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

    Depatment Entity不会包含forign key的任何mappping ...所以现在当你在单个json请求中尝试使用Department添加Employee的POST请求时,它将被添加....

  • 48

    我遇到了相同的场景,我不得不删除子实体的存储库类,因为我使用了一对多映射并通过主实体本身提取数据 . 现在我得到了整个数据响应 .

  • 1

    对于oneToMany映射,只需为要映射的类创建一个POJO,并为其创建@OneToMany注释,并在内部将其映射到该表ID .

    此外,您需要将Serializable接口实现为要检索数据的类 .

相关问题