Spring Data Rest - 存储库上的 PUT 在子引用上静默失败 [英] Spring Data Rest - PUT on repository silently fails on child references
问题描述
我使用 Spring Data Rest
和 Spring Boot
2.1.1.RELEASE.
I use Spring Data Rest
with Spring Boot
2.1.1.RELEASE.
我有一个 User
类,它与 Skill
类具有 @ManyToMany
关系.
I have a class User
with a @ManyToMany
relationship to a class Skill
.
- 当我使用
POST
创建一个具有他技能的用户时,一切正常. - 当我做一个
PUT
来更新用户时,技能没有更新,没有产生错误. - 但是当我制作
PATCH
而不是PUT
时,技能会正确更新.
- When I make a
POST
to create a user with his skills, everything works finely. - When I make a
PUT
to update a user, the skills are not updated, no error is produced. - But when I make a
PATCH
instead of aPUT
, the skills are correctly updated.
有人遇到过类似的问题吗?我发现了另一个(旧)问题,但没有解决方案(Spring Data Rest - PUT 不适用于关联的引用类型?)
Have anyone met a similar issue? I have found another (old) question about it, but there isn't solution (Spring Data Rest - PUT is not working for associated reference types?)
我可能在某处错过了一些东西......
I probably have missed something, somewhere...
(使用 Lombok 的代码)
(Code using Lombok)
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
@ManyToMany
@JoinTable(name="user_skills")
private List<Skill> skills = new ArrayList<>();
}
@Entity
@Getter
@Setter
@NoArgsConstructor
@ToString
public class Skill {
@Id
@GeneratedValue
private Long id;
private String name;
}
我使用以下 JSON
内容制作了一个 PUT
:
I make a PUT
with the following JSON
content:
{
"id": 7,
"firstName": "John",
"lastName": "Doe",
"skills": ["http://localhost:9001/skills/1", "http://localhost:9001/skills/2", "http://localhost:9001/skills/3"]
}
firstName 或 lastName 可以修改,但技能保持不变.
The firstName or lastName can be modified, but the skills remain unmodified.
如果我用相同的payload做一个PATCH
,技能就被正确修改了.
If I do a PATCH
with the same payload, the skills are correctly modified.
它应该与 PUT
一起工作,不是吗?
It should work with a PUT
, doesn't it?
推荐答案
经过多方调查,看来这种行为是故意的:PUT 不更新资源链接,只更新主要属性.
After more investigations, it seems that this behaviour is by purpose: PUT does not update the resource links, only the main attributes.
Oliver Gierke 的答案在这里:https://jira.spring.io/browse/DATAREST-1001?focusedCommentId=135791&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-135791:
The answer from Oliver Gierke is here: https://jira.spring.io/browse/DATAREST-1001?focusedCommentId=135791&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-135791:
我对此进行了调查,我认为您期望事情以他们不工作的方式工作.PUT 请求不考虑与可链接资源的关联,即链接指向的相关资源.原因有两个:
I looked into this and I'd argue you're expecting things to work in a way they don't work. PUT requests don't consider associations to linkable resources, i.e. related resources that are pointed to by links. The reason for that is two-fold:
- 如果我们考虑使用负载中关联字段的 URI 来更新这些关联,那么问题就出现了,如果未指定 URI,会发生什么情况.对于当前行为,链接关联根本不是有效负载的一部分,因为它们仅驻留在 _links 块中.在这种情况下,我们有两个选择:擦除未处理的关联,这打破了PUT what you GET";方法.仅擦除使用 null 提供的那些会模糊您放置了资源的整个状态".
- 出于 1. 中提到的所有原因,公开了可以直接操作的专用关联资源.
所以看起来如果你想同时改变资源和关联的状态,我想公开一个专用资源来做到这一点.
So it looks like that if you want to change both state of the resource plus associations at the same time, I guess exposing a dedicated resource to do that is the way to go.
其他帖子和链接:
- 无法使用项目资源上的 PUT 请求更新关联资源":https://jira.spring.io/browse/DATAREST-1001
- Spring Data Rest PUT v.s PATCH LinkableResources": Spring Data Rest PUT vs PATCH LinkableResources
- PUT 的行为类似于嵌套集合的 PATCH":https://jira.spring.io/browse/DATAREST-1012
这篇关于Spring Data Rest - 存储库上的 PUT 在子引用上静默失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!