如何解决Spring boot JPA - 双向关系:返回外键而不是相关对象
我有两个实体:客户和地址。
这是一种双向关系 - 一个地址可以有多个客户(onetoMany),一个客户只能有一个地址(manyToOne)。
为客户退货执行 GET 请求:
[
{
"id": 1,"name": "Foo","contact": "5512312","email": "Foo@gmail.com","address": {
"id": 1,"street": "X","postalCode": 123,"houseNo": "10","city": "New York"
}
}
]
当一个新客户的地址属性与数据库中存在的完全相同时 - 正在通过 POST 请求添加,json 响应返回与数据库中现有对象相关的外键,而不是对象本身:>
[
{
"id": 1,"city": "New York"
}
},{
"id": 2,"name": "Bar","email": "Bar@gmail.com","address": 1 <----------- it returns the foreign key instead of the object
}
]
所以我期望是,每当一个新客户的地址已经存在在数据库中时,被添加 - 它应该返回地址对象而不是来自json响应的外键。
代码:
Customer.java
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
@Entity
@Table
public class Customer {
@Id
@SequenceGenerator(
name = "customer_sequence",sequenceName = "customer_sequence",allocationSize = 1
)
@GeneratedValue(
strategy = GenerationType.SEQUENCE,generator = "customer_sequence"
)
private Long id;
private String name;
private String contact;
private String email;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id",nullable = false)
private Address address;
[...]
Address.java
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
@Entity
@Table
public class Address {
@Id
@SequenceGenerator(
name = "address_sequence",sequenceName = "address_sequence",generator = "address_sequence"
)
private Long id;
private String street;
private int postalCode;
private String houseNo;
private String city;
@JsonIgnore
@OnetoMany(mappedBy = "address")
private Set<Customer> customers;
[...]
CustomerController.java
//...
@PostMapping
public void createCustomer(@RequestBody Customer customer) {
customerService.createCustomer(customer);
}
[...]
服务将客户保存到数据库中,这也确保如果数据库中已经存在地址,则不会创建任何地址(它检查每个属性等于参数):
//...
public void createCustomer(Customer customer) {
Optional<Customer> customerWithExistingAddress = customerRepository.findAll()
.stream()
.filter(x -> x.getAddress().equals(customer.getAddress()))
.findFirst();
customerWithExistingAddress.ifPresent(c -> customer.setAddress(c.getAddress()));
customerRepository.save(customer);
}
[...]
解决方法
您可能因为 JsonIdentityInfo 而得到这种行为,所以这是一个序列化问题,您没有持久性问题。我假设您使用的是关系数据库(NoSql 的 Hibernate 具有 Jpa 之类的注释,但这会使这成为一个不同的问题)并且数据被正确持久化。
在实践中,这是通过将第一个实例序列化为完整对象和对象标识,并将对对象的其他引用作为引用值来完成的
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。