Spring Data Rest - PUT on repository silently fails on child references

穿精又带淫゛_ 提交于 2019-12-12 20:28:30

问题


I use Spring Data Rest with Spring Boot 2.1.1.RELEASE.

I have a class User with a @ManyToMany relationship to a class Skill.

  • 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 a PUT, the skills are correctly updated.

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

(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;
}

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"]
}

The firstName or lastName can be modified, but the skills remain unmodified.

If I do a PATCH with the same payload, the skills are correctly modified.

It should work with a PUT, doesn't it?


回答1:


After more investigations, it seems that this behaviour is by purpose: PUT does not update the resource links, only the main attributes.

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:

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:

  1. 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".
  2. 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.

Other posts and links:

  • "Unable to update associated resource using PUT request on the item resource": https://jira.spring.io/browse/DATAREST-1001
  • "Spring Data Rest PUT v.s PATCH LinkableResources" : Spring Data Rest PUT v.s PATCH LinkableResources
  • "PUT behaving like PATCH for nested collections": https://jira.spring.io/browse/DATAREST-1012


来源:https://stackoverflow.com/questions/54445706/spring-data-rest-put-on-repository-silently-fails-on-child-references

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!