Java 在 Spring Data REST 中发布 @OneToMany 子资源关联
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25311978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
POSTing a @OneToMany sub-resource association in Spring Data REST
提问by ccampo
Currently I have a Spring Boot application using Spring Data REST. I have a domain entity Post
which has the @OneToMany
relationship to another domain entity, Comment
. These classes are structured as follows:
目前我有一个使用 Spring Data REST 的 Spring Boot 应用程序。我有一个域实体Post
,它@OneToMany
与另一个域实体Comment
. 这些类的结构如下:
Post.java:
后.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:
评论.java:
@Entity
public class Comment {
@Id
@GeneratedValue
private long id;
private String author;
private String content;
@ManyToOne
private Post post;
// Standard getters and setters...
}
Their Spring Data REST JPA repositories are basic implementations of CrudRepository
:
他们的 Spring Data REST JPA 存储库是以下的基本实现CrudRepository
:
PostRepository.java:
PostRepository.java:
public interface PostRepository extends CrudRepository<Post, Long> { }
CommentRepository.java:
CommentRepository.java:
public interface CommentRepository extends CrudRepository<Comment, Long> { }
The application entry point is a standard, simple Spring Boot application. Everything is configured stock.
应用程序入口点是一个标准的、简单的 Spring Boot 应用程序。一切都是配置库存。
Application.java
应用程序.java
@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Everything appears to work correctly. When I run the application, everything appears to work correctly. I can POST a new Post object to http://localhost:8080/posts
like so:
一切似乎都正常工作。当我运行该应用程序时,一切似乎都正常工作。我可以http://localhost:8080/posts
像这样发布一个新的 Post 对象:
Body:
{"author":"testAuthor", "title":"test", "content":"hello world"}
身体:
{"author":"testAuthor", "title":"test", "content":"hello world"}
Result at http://localhost:8080/posts/1
:
结果在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.
但是,当我执行 GET 时,返回http://localhost:8080/posts/1/comments
一个空对象{}
,如果我尝试向同一个 URI 发布评论,我会得到一个 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.
创建Comment
资源并将其与此关联的正确方法是什么Post
?http://localhost:8080/comments
如果可能,我想避免直接发布。
采纳答案by Chetan Kokil
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.
它会工作得很好。
回答by Oliver Drotbohm
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:
假设你已经发现了post URI,因此也发现了关联资源的URI(考虑$association_uri
在下面),它通常采取以下步骤:
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
发现收藏资源管理评论:
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
通过向
PUT
关联 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.
请注意,在最后一步中,根据 的规范text/uri-list
,您可以提交多个 URI 标识注释,以换行符分隔,以便一次分配多个注释。
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 thatin the latest release candidate for the upcoming version 2.2.
关于一般设计决策的更多说明。帖子/评论示例通常是聚合的一个很好的示例,这意味着我会避免从 theComment
到 the的反向引用Post
,也避免CommentRepository
完全。如果注释本身没有生命周期(它们通常没有组合风格的关系),您宁愿直接内联呈现注释,并且可以通过使用来处理添加和删除注释的整个过程JSON 补丁。Spring Data REST在即将发布的 2.2 版的最新候选版本中增加了对此的支持。
回答by Selva
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.
我遇到了同样的情况,我不得不删除子实体的存储库类,因为我使用了一对多映射并通过主实体本身提取数据。现在我得到了完整的数据响应。
回答by Naveen Goyal
There are 2 types of mapping Association and Composition. In case of association we used join table concept like
映射关联和组合有两种类型。在关联的情况下,我们使用连接表概念,如
Employee--1 to n-> Department
员工--1到n->部门
So 3 tables will be created in case of Association Employee, Department, Employee_Department
因此,在 Association Employee、Department、Employee_Department 的情况下将创建 3 个表
You only need to create the EmployeeRepository in you code. Apart from that mapping should be like that:
您只需要在代码中创建 EmployeeRepository。除此之外,映射应该是这样的:
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....
部门实体将不包含任何外键映射...所以现在当您尝试在单个 json 请求中添加带有部门的员工的 POST 请求时,它将被添加...。
回答by Sunny Chaurasia
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.
对于 oneToMany 映射,只需为要映射的类创建一个 POJO,并为其添加 @OneToMany 注释,然后在内部将其映射到该表 ID。
Also, you need to implement the Serializable interface to the class you are retrieving the Data.
此外,您需要为正在检索数据的类实现 Serializable 接口。