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

标签 java spring spring-boot spring-data-jpa spring-data-rest

目前我有一个使用 Spring Data REST 的 Spring Boot 应用程序。我有一个域实体 Post,它与另一个域实体 Comment@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...
}

评论.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);
    }
}

一切似乎都正常工作。当我运行该应用程序时,一切似乎都正常工作。我可以像这样向 http://localhost:8080/posts 发布一个新的 Post 对象:

body : {"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 发布评论,我得到一个 HTTP 405 Method Not Allowed。

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

最佳答案

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

  1. 发现 Collection 资源管理评论:

     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 标识以换行符分隔的评论,以便一次分配多条评论。

关于一般设计决策的更多说明。 post/comments 示例通常是聚合的一个很好的示例,这意味着我会避免从 CommentPost 的反向引用,同时也避免 CommentRepository 完全。如果评论没有自己的生命周期(它们通常没有组合风格的关系),您宁愿直接内联呈现评论,并且可以通过使用来处理添加和删除评论的整个过程JSON Patch . Spring Data REST 已添加 support for that在即将发布的 2.2 版的最新候选版本中。

关于java - 在 Spring Data REST 中发布 @OneToMany 子资源关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25311978/

相关文章:

java - 输出未按预期显示

java - 我应该 try catch 任何 EnityManager 查询异常吗?

java - 库没有JAVADOC代码完整求助

java - 如何从 Internet 获取值到 String[] 数组并将其传递到 Android 中的 GridView ?

java - 使用 Spring 集成将 pojo 插入数据库

java - 使用所属类的lazy-init选项运行计划方法

spring - DataNucleus:查询的类...尚未解决。检查查询和任何进口规范

java - Flyway 与 spring boot 的集成不会在嵌入式 H2 数据库上执行迁移脚本

java - 在服务器中隐藏 key 或外部化应用程序属性

java - Spring boot Http Security 配置单元测试