Spring 数据 Rest - PUT 到存储库在子引用上静默失败
Spring Data Rest - PUT on repository silently fails on child references
我使用 Spring Data Rest
和 Spring Boot
2.1.1.RELEASE.
我有一个 class User
与 class Skill
.
有 @ManyToMany
关系
- 当我用他的技能
POST
创建一个用户时,一切正常。
- 当我
PUT
更新用户时,技能没有更新,没有产生错误。
- 但是当我制作
PATCH
而不是 PUT
时,技能会正确更新。
有没有人遇到过类似的问题?
我发现了另一个(旧的)问题,但没有解决方案 (Spring Data Rest - PUT is not working for associated reference types?)
我可能在某处遗漏了一些东西...
(使用 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;
}
我制作了一个PUT
,内容如下JSON
:
{
"id": 7,
"firstName": "John",
"lastName": "Doe",
"skills": ["http://localhost:9001/skills/1", "http://localhost:9001/skills/2", "http://localhost:9001/skills/3"]
}
可以修改名字或姓氏,但技能保持不变。
如果我使用相同的负载执行 PATCH
,技能会正确修改。
它应该与 PUT
一起使用,不是吗?
经过更多调查,这种行为似乎是故意的:PUT 不更新资源链接,只更新主要属性。
Oliver Gierke 的回答在这里:https://jira.spring.io/browse/DATAREST-1001?focusedCommentId=135791&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-135791:
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:
- If we consider URIs for association fields in the payload to update those associations, the question comes up about what's supposed to happen if no URI is specified. With the current behavior, linked associations are simply not a part of the payload as they only reside in the _links block. We have two options in this scenario: wiping the associations that are not handed, which breaks the "PUT what you GET" approach. Only wiping the ones that are supplied using null would sort of blur the "you PUT the entire state of the resource".
- For all the reasons mentioned in 1. there are dedicated assoctiation resources exposed that can be manipulated directly.
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 数据 Rest PUT v.s PATCH LinkableResources" : Spring Data Rest PUT v.s PATCH LinkableResources
- “PUT 的行为类似于嵌套集合的 PATCH”:https://jira.spring.io/browse/DATAREST-1012
我使用 Spring Data Rest
和 Spring Boot
2.1.1.RELEASE.
我有一个 class User
与 class Skill
.
@ManyToMany
关系
- 当我用他的技能
POST
创建一个用户时,一切正常。 - 当我
PUT
更新用户时,技能没有更新,没有产生错误。 - 但是当我制作
PATCH
而不是PUT
时,技能会正确更新。
有没有人遇到过类似的问题? 我发现了另一个(旧的)问题,但没有解决方案 (Spring Data Rest - PUT is not working for associated reference types?)
我可能在某处遗漏了一些东西...
(使用 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;
}
我制作了一个PUT
,内容如下JSON
:
{
"id": 7,
"firstName": "John",
"lastName": "Doe",
"skills": ["http://localhost:9001/skills/1", "http://localhost:9001/skills/2", "http://localhost:9001/skills/3"]
}
可以修改名字或姓氏,但技能保持不变。
如果我使用相同的负载执行 PATCH
,技能会正确修改。
它应该与 PUT
一起使用,不是吗?
经过更多调查,这种行为似乎是故意的:PUT 不更新资源链接,只更新主要属性。
Oliver Gierke 的回答在这里:https://jira.spring.io/browse/DATAREST-1001?focusedCommentId=135791&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-135791:
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:
- If we consider URIs for association fields in the payload to update those associations, the question comes up about what's supposed to happen if no URI is specified. With the current behavior, linked associations are simply not a part of the payload as they only reside in the _links block. We have two options in this scenario: wiping the associations that are not handed, which breaks the "PUT what you GET" approach. Only wiping the ones that are supplied using null would sort of blur the "you PUT the entire state of the resource".
- For all the reasons mentioned in 1. there are dedicated assoctiation resources exposed that can be manipulated directly.
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 数据 Rest PUT v.s PATCH LinkableResources" : Spring Data Rest PUT v.s PATCH LinkableResources
- “PUT 的行为类似于嵌套集合的 PATCH”:https://jira.spring.io/browse/DATAREST-1012