如何解决从Json正确创建的实体,在另一侧有@JoinColumn
我以为我了解了JPA的 @JoinColumns 批注和 mappedBy 参数,但是随后我需要根据这个 Question 问题的Json创建新实体>。它具有一组答案选择,这些答案也需要映射到新实体。我决定Question实体将成为拥有方,因此我省略了mappingBy参数。当我在 AnswerChoice 端使用@JoinColumns批注时,所有实体都是从Json对象创建的,但是没有设置AnswerChoices对Question实体的FK。
将@JoinColumns放到Question实体中解决了问题,但是我的问题是:这是正确的方法吗?我会面临任何副作用吗?相反,我应该在AnswerChoices集合上运行for循环并设置FK吗?
问题杰森
{
"text": "Do you kNow JPA?","answerChoices": [{
"text": "yes",},{
"text": "no",]
}
具有JpaRepository的控制器:
@PostMapping("/questions/create")
@ResponseBody
public String create(@RequestBody Question json) {
questionRepo.save(json);
}
问题实体:
@Entity
public class Question {
@OnetoMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@JoinColumn(name="question_id")
private Set<AnswerChoice> answerChoices;
}
AnswerChoice实体:
@Entity
public class AnswerChoice {
@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnore
private Question question;
}
解决方法
不是,映射不正确。实际上,它创建两个碰巧共享连接列的单独关联。
从question
中删除Answer
,使关联成为单向关联(如果您确实需要关联的那一面,请问问自己),或者返回原始解决方案并使用@JsonBackReference/@JsonManagedReference
(因此在反序列化期间该字段会自动填充)。
如@crizzis所述,您的映射是不正确的,通常,孩子是关系的所有者(当一对多对一个域很大时),但是在您的情况下,{{1 }}是关系的拥有方,因为您拥有Question
。因此,您可以完全摆脱@JoinColumn
的{{1}}参考。当您创建带有“答案”选项的“问题”时,休眠状态将
- 提出问题
- 创建答案
- 更新答案问题的外键
如果您从Question实体中删除此行Question
,则hibernate将创建额外的表来管理称为AnswerChoice
的这种关系,因此要摆脱多余的表,我们将手动指定{{ 1}}映射到外键。
实体@JoinColumn(name = "question_id",foreignKey = @ForeignKey(name = "fk_question_id"))
question_answer_choices
实体AnswerChoice
Question.java
下面的测试代码
@Entity
@Table(name = "question")
public class Question {
@Id
@GeneratedValue
@Type(type = "uuid-char")
private UUID id;
private String description;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "question_id",foreignKey = @ForeignKey(name = "fk_question_id"))
private Set<AnswerChoice> answerChoices = new HashSet<>();
public UUID getId() {
return id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void addAnswerChoice(AnswerChoice answerChoice) {
if (answerChoice != null) {
this.answerChoices.add(answerChoice);
}
}
public Set<AnswerChoice> getAnswerChoices() {
return answerChoices;
}
}
生成的表语句如下:
questions.sql
AnswerChoice.java
answer_choice.sql
@Entity
@Table(name = "answer_choice")
public class AnswerChoice {
@Id
@GeneratedValue
@Type(type = "uuid-char")
private UUID id;
private String content;
public AnswerChoice() {
}
public AnswerChoice(String content) {
this.content = content;
}
public UUID getId() {
return id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。