Spring Data Rest - PUT в репозитории молча терпит неудачу при дочерних ссылках

Я использую Spring Data Rest с Spring Boot 2.1.1.RELEASE.

У меня есть класс User с отношением @ManyToMany к классу Skill.

  • Когда я делаю POST для создания пользователя с его навыками, все работает нормально.
  • Когда я делаю PUT для обновления пользователя, навыки не обновляются, ошибка не выдается.
  • Но когда я делаю PATCH вместо PUT, скиллы корректно обновляются.

Кто-нибудь встречал подобную проблему? Я нашел другой (старый) вопрос по этому поводу, но решения нет (Spring Data Rest - PUT не работает для связанных ссылочных типов?)

Я, наверное, что-то где-то пропустил...

(Код с использованием Ломбока)

@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, не так ли?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
421
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После дополнительных исследований кажется, что такое поведение является преднамеренным: 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:

  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.

Другие посты и ссылки:

Другие вопросы по теме