Spring Data Rest - PUT不适用于相关的参考类型?

时间:2017-05-22 15:46:26

标签: spring rest spring-boot spring-data-rest spring-hateoas

我为Spring Data Rest项目实现了以下域类。

@Entity
@Data
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long addressID;

    private String houseName;

    private String apartmentNumber;

    @ManyToOne
    private City city;

    @ManyToOne
    private Country country; 

}

现在我通过发送带有以下JSON的POST来创建一个Address资源。

{   
    "houseName":"Some House",
    "apartmentNumber":"13 B",
    "city": "http://localhost:8080/city/1"
    "country":"http://localhost:8080/countries/1"
}

当我使用以下JSON向端点http://localhost:8080/addresses/1发送PUT请求时,会更新houseName的值。然而,即使我为该城市发送了不同的URI,城市仍保持不变。

{   
    "houseName":"Another House",
    "apartmentNumber":"13 B",
    "city": "http://localhost:8080/city/2"
    "country":"http://localhost:8080/countries/1"
}

如果我发送PATCH而不是PUT,则城市值也会更新。那么我该如何解决这个问题?

更新1

国家/地区

@Data
@Entity
public class Country {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long countryID;

    private String countryName;

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

}

城市班

@Data
@Entity
public class City {

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

    private String cityName;

    @ManyToOne
    @JoinColumn(name = "country_id")
    private Country country;
}

2 个答案:

答案 0 :(得分:0)

如果您正在使用Hibernate作为JPA提供程序,那么您必须知道实体在两个方面的映射方式,并指出它在子实体中的映射方式,这将关注如何管理关系。事务。

已编辑及更新:

//城市类

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

//国家/地区

@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:如果您正在更新部分资源,资源和关系的子集

USE PUT:如果您使用全新的代表替换资源

答案 1 :(得分:0)

我遇到了同样的问题,并设法找到了一些信息。

这是2.5.7的{​​{1}}版本的更改,是“有目的的”。

Oliver Drotbohm的答案是:

  

我调查了一下,我认为您期望事情能够在   他们不工作的方式。 PUT请求不考虑与   可链接资源,即由指向的相关资源   链接。其原因有两个:

     
      
  1. 如果我们考虑有效载荷中关联字段的URI以更新这些关联,则会出现有关应该如何处理的问题   如果未指定URI,则会发生。与当前行为相关联   关联根本就不是有效载荷的一部分,因为它们只存在   在_links块中。在这种情况下,我们有两种选择:   未处理的关联,这会破坏“输入所获得的内容”   方法。仅擦除使用null提供的内容进行排序   模糊化“您放置资源的整个状态”。
  2.   
  3. 出于1.中提到的所有原因,公开了专用的联合资源,可以直接对其进行操作。
  4.   
     

因此,如果您想同时更改资源的两个状态,则看起来像这样   加上同一时间的联想,我想暴露一个专门的   做到这一点的资源是必经之路。

您可以在Jira Spring网站上找到完整答案:Unable to update associated resource using PUT request on the item resource

(我在堆栈溢出上写的问题在这里:Spring Data Rest - PUT on repository silently fails on child references