Java 使用Spring数据Rest,如何从一个Rest调用更新OneToOne关系两侧的FK?
我有一个带有Java 使用Spring数据Rest,如何从一个Rest调用更新OneToOne关系两侧的FK?,java,spring-boot,spring-data-jpa,spring-data-rest,spring-hateoas,Java,Spring Boot,Spring Data Jpa,Spring Data Rest,Spring Hateoas,我有一个带有 弹簧启动启动器数据rest spring引导启动器数据jpa 氢 我有这样一对一关系的实体: @Entity public class Address { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long key; @OneToOne(cascade = ALL) @JoinColumn(name = "party") private Pa
- 弹簧启动启动器数据rest
- spring引导启动器数据jpa
- 氢
@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;
....
}
以及每个实体的存储库:
@RepositoryRestResource
public interface AddressRepository extends JpaRepository<Address, Long> { }
curl -X POST \
-H 'Content-Type: application/json' \
-d '{ "name": "John Smith" }' \
http://localhost:8080/parties
在address实例上,我创建了一个与party的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
curl -X GET http://localhost:8080/parties/1/address -i
我看到了正确的一方:
HTTP/1.1 200
{
"key" : 1,
"name" : "John Smith",
....
}
但是,当我检查地址的关联时:
curl -X GET http://localhost:8080/addresses/1/party -i
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;
}
当我测试时,效果很好。两张桌子都省了钱
卷曲
curl -X http://localhost:8080/parties/1
我在我的
聚会
课堂上找到了解决方案:
@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);
}
}
以下是我的应用程序流程:
你能给我们看看你在party中保存的java代码吗?在上面,保存由JpaRepository代理并作为帖子公开。它不在那里,事实上,我想看看你在哪里调用repository.save,我怀疑你在保存party时没有填充地址,理想情况下,当您使用main方法保存party address时,它也应该是savedOther,而不是@SpringBootApplication类,这就是整个应用程序(减去getter/setter)。没有手动调用repository.save——这是由spring-data-REST自动代理到REST端点的。好的,刚刚意识到您使用的是@RepositoryRestResource,虽然您使用的是@RepositoryI,但我不想在创建时创建关联。我想创建实体,然后在以后应用一个关联,该关联应应用于两个实体的FK。无论我是将关联应用于来自party的address还是来自address的party,我都希望两个FK都会更新,但我观察到只有一个更新被应用。嗯,我认为,您只能保留它的一侧。假设您必须使用sql添加数据,最终将编写两个insert和两个UPDATE。我找到了解决方案,请参阅我的回答。虽然我使用相同的方法维护上次更新的实体,但我没有想到这一点。
@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