使用 Spring-Data-Rest,如何从一个 REST 调用更新 OneToOne 关系两侧的 FK?

Using Spring-Data-Rest, how to update FK on both sides of OneToOne relationship from one REST call?

我有一个Spring-启动应用

我有这样一对一关系的实体:

@Entity
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long key;

    @OneToOne(cascade = ALL)
    @JoinColumn(name = "party")
    private Party party;

    @Column
    private String street;

    ....
}
@Entity
public class Party {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long key;

    @Column
    private String name;

    @OneToOne(cascade = ALL)
    @JoinColumn(name  = "address")
    private Address address;

    ...

}

每个实体的存储库:

@RepositoryRestResource
public interface AddressRepository extends JpaRepository<Address, Long> { }
@RepositoryRestResource
public interface PartyRepository extends JpaRepository<Party, Long> { }

我为每个实体创建一个实例:

curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{ "name": "John Smith" }' \
     http://localhost:8080/parties
curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{ "street": "456 main st" }' \
     http://localhost:8080/addresses

在地址实例上,我创建了一个 HATEOAS 关联方:

curl -X PUT \
     -H 'Content-Type: text/uri-list' \
     -d http://localhost:8080/parties/1 \
     http://localhost:8080/addresses/1/party

当我检查地址的关联时:

curl -X GET http://localhost:8080/addresses/1/party -i

我看到正确的一方:

HTTP/1.1 200 
{
  "key" : 1,
  "name" : "John Smith",
  ....
}

但是,当我检查地址的关联时:

curl -X GET http://localhost:8080/parties/1/address -i

不存在:

HTTP/1.1 404 

如何使用 Spring-Data-Rest 从单个调用创建两个关联?

你需要像下面那样执行你的 curl

curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{ "name": "John Smith" , "address":{ "street": "456 main st" }}' \
     http://localhost:8080/parties

我在实体中做了一些小改动

@Entity
public class Party implements Serializable{


    private static final long serialVersionUID = 1735292011581348691L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long key;

    @Column
    @JsonProperty("name")
    private String name;

    @JsonProperty("address")
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name  = "address")
    private Address address;


}

@Entity
public class Address implements Serializable {
private static final long serialVersionUID = -7468012139122259209L;


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long key;


    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "party")
    private Party party;

    @JsonProperty("street")
    @Column
    private String street;

}

我测试时工作正常。 table

都节省了

卷曲得到

curl -X  http://localhost:8080/parties/1

我在 Party class:

上使用 @PrePersist and @PreUpdate 找到了解决方案
@Entity
public class Party {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long key;

    @Column
    private String name;

    @OneToOne(cascade = ALL)
    @JoinColumn(name  = "address")
    private Address address;

    @PrePersist
    @PreUpdate
    public void updateAddressAssociation() {
        if (address != null)
            address.setParty(this);
    }

}

这是我的应用流程:

  1. 创建地址:
curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{ "street": "456 main st" }' \
     http://localhost:8080/addresses
  1. 创建派对
curl -X POST \
     -H 'Content-Type: application/json' \
     -d '{ "name": "John Smith" }' \
     http://localhost:8080/parties
  1. 将地址与派对相关联
curl -X PUT \
     -H 'Content-Type: text/uri-list' \
     -d http://localhost:8080/parties/1 \
     http://localhost:8080/addresses/1/party
  1. 确认一方有地址关联
curl http://localhost:8080/parties/1/address
  1. 确认地址有党组织
curl http://localhost:8080/addresses/1/party