我有两个实体“员工”和“审核”。我正在尝试创建一对一关系“员工 <-> 审核”。
当我用评论更新员工时,员工会更新,评论将成为相应的评论, 但评论没有添加带有员工 ID 的“评论者”列,这正是我所期望的。
我做错了什么?
这些是我的实体:
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "reviewee")
private Review review;
}
public class Review {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String body;
private char completed;
@OneToOne(mappedBy = "review")
private Employee reviewee;
}
这是我的employeeController更新函数:
@GetMapping(path="/update")
public @ResponseBody Employee updateEmployee (@RequestParam Integer id,
@RequestParam(value = "name", required=false) String name,
@RequestParam(value = "email", required=false) String email,
@RequestParam() Integer reviewId) {
Employee n = EmployeeRepository.findOne(id);
if(name == null) {
name = n.getName();
}
if(email == null) {
email = n.getEmail();
}
n.setName(name);
n.setEmail(email);
Review r = ReviewRepository.findOne(reviewId);
n.setReview(r);
EmployeeRepository.save(n);
return n;
}
请求:
curl 'localhost:8080/employees/update?id=2&reviewId=1'
最佳答案
由于关系的所有者(带有 @JoinColumn
的所有者)是 Employee
,因此您必须通过保存 Employee 来创建/更新/删除关联
对象。
这就是您到目前为止正在做的事情。但 Hibernate 只会在您保存时更新所有者。您还应该在返回实体之前执行此操作:
r.setReviewee(n);
请注意,下次您检索评论时,它将正确地具有 Employee
对象。
注意:序列化时我闻到了 Jackson 无限循环的味道。
Employee.review -> Review -> Review.reviewee -> Employee -> Employee.review...
编辑
为了防止 jackson 无限循环:
1.忽略序列化。
Employee.java
public class Employee {
// ...
// Do not serialize this field
@JsonIgnore
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "reviewee")
private Review review;
// ...
}
2.序列化为ID。
Employee.java
public class Employee {
// ...
// Serialize as a single value with the field "id"
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
// Serialize as told by @JsonIdentityInfo immediately (if false -> on second and further occurrences)
@JsonIdentityReference(alwaysAsId = true)
// Rename to "review_id" (would be "review" otherwise)
@JsonProperty(value = "review_id")
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "reviewee")
private Review review;
// ...
}
3.序列化为 ID 的替代方案:对外键的只读引用。
Employee.java
public class Employee {
// ...
// Do not serialize this field
@JsonIgnore
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "reviewee")
private Review review;
// Read-only access to the foreign key
@Column(name = "Review_id", insertable = false, updatable = false)
private Integer reviewId;
// ...
}
关于java - Spring boot - 更新一个实体后,一对一关系未反射(reflect)在两个表上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42871018/