Spring Data Rest - PUT is not working for associated reference types?

只谈情不闲聊 提交于 2019-12-06 04:23:24
Cyril Gambis

I had the same problem and manage to find some information on it.

It is a change in version 2.5.7 of Spring Data Rest and is "by purpose".

The answer of Oliver Drotbohm is:

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.

Full answer you can find on Jira Spring site: Unable to update associated resource using PUT request on the item resource

(the question I wrote on stack overflow is here: Spring Data Rest - PUT on repository silently fails on child references)

If you're using Hibernate as your JPA provider, then you must let know how the entities are mapped in both the sides and indicate the how it is mapped in the child entity which will take care how the relationships are managed during a transaction.

EDITED and UPDATED:

// City Class

@Entity
public class City {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "city_id")
    private Long cityID;

    @Column(name = "city_name")
    private String cityName;

    @ManyToOne
    private Country country;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "city", orphanRemoval = true)
    private List<Address> addresses;
}

// Country Class

@Entity
public class Country {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "country_id")
    private Long countryID;

    @Column(name = "country_name")
    private String countryName;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "country", orphanRemoval = true)
    private List<City> cities = new ArrayList<>();;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "country", orphanRemoval = true)
    private List<Address> addresses;
}

USE PATCH: If you're updating part of the resource, subset of the resource and relationships

USE PUT: If you're replacing the resource with an entirely new representation

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