使用 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-启动应用
- spring-boot-starter-data-rest
- spring-boot-starter-data-jpa
- h2
我有这样一对一关系的实体:
@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);
}
}
这是我的应用流程:
- 创建地址:
curl -X POST \
-H 'Content-Type: application/json' \
-d '{ "street": "456 main st" }' \
http://localhost:8080/addresses
- 创建派对
curl -X POST \
-H 'Content-Type: application/json' \
-d '{ "name": "John Smith" }' \
http://localhost:8080/parties
- 将地址与派对相关联
curl -X PUT \
-H 'Content-Type: text/uri-list' \
-d http://localhost:8080/parties/1 \
http://localhost:8080/addresses/1/party
- 确认一方有地址关联
curl http://localhost:8080/parties/1/address
- 确认地址有党组织
curl http://localhost:8080/addresses/1/party
我有一个Spring-启动应用
- spring-boot-starter-data-rest
- spring-boot-starter-data-jpa
- h2
我有这样一对一关系的实体:
@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:
@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);
}
}
这是我的应用流程:
- 创建地址:
curl -X POST \
-H 'Content-Type: application/json' \
-d '{ "street": "456 main st" }' \
http://localhost:8080/addresses
- 创建派对
curl -X POST \
-H 'Content-Type: application/json' \
-d '{ "name": "John Smith" }' \
http://localhost:8080/parties
- 将地址与派对相关联
curl -X PUT \
-H 'Content-Type: text/uri-list' \
-d http://localhost:8080/parties/1 \
http://localhost:8080/addresses/1/party
- 确认一方有地址关联
curl http://localhost:8080/parties/1/address
- 确认地址有党组织
curl http://localhost:8080/addresses/1/party