我有两个实体Employee and Review。我正在尝试创建OneToOne关系Employee< - >评论。
当我通过审核更新员工时,员工会在审核成为相应审核的地方得到更新, 但是评论没有得到评论者的认可。列添加了员工的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'
答案 0 :(得分:1)
由于关系的所有者(@JoinColumn
)的所有者是Employee
,因此您必须通过保存Employee
对象来创建/更新/删除关联。
这是你到目前为止所做的。但是Hibernate只会在保存时更新所有者。此外,您应该在返回实体之前执行此操作:
r.setReviewee(n);
请注意,下次检索审核时,它会正确显示Employee
个对象。
注意:序列化时,我闻到了杰克逊的无限循环。
Employee.review -> Review -> Review.reviewee -> Employee -> Employee.review...
修改强>
防止杰克逊无限循环:
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;
// ...
}
答案 1 :(得分:0)
它似乎是配置不匹配。请尝试下面的一个。
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String email;
@OneToOne(mappedBy="reviewee",cascade = CascadeType.ALL)
private Review review; }
public class Review {
@Id
@GeneratedValue(generator="gen")
@GenericGenerator(name="gen", strategy="foreign", parameters={@Parameter(name="property",value="reviewee")})
private Integer id;
private String body;
private char completed;
@OneToOne
@PrimaryKeJoinCloumn
private Employee reviewee; }
我希望上面的配置按预期工作。
请确保您在“交易边界”下调用保存功能。否则,在关闭会话之前不要忘记调用flush()。