【发布时间】:2015-11-12 21:38:19
【问题描述】:
这个问题已经被问过很多次了,但是我没有找到任何好的答案,所以我会再问一次。
我的父子单向关系如下:
@Entity
@Table(name = "PARENT")
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long parentId;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinTable(name = "CHILD", joinColumns = @JoinColumn(name = "parent_id"), inverseJoinColumns = @JoinColumn(name = "ID"))
private List<Child> children;
}
@Entity
@Table(name = "CHILD")
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "PARENT_ID")
private Long parentId;
//some other field
}
我创建一个父实例,为其分配一个子列表并尝试将其持久化:
Parent p = new Parent();
List<Child> children = new ArrayList<Child>();
Child c = new Child();
children.add(c);
p.addChildren(children);
em.merge(p);
当代码运行时,我得到以下异常:
MySQLIntegrityConstraintViolationException:无法添加或更新 子行:外键约束失败 (
testdb.child,约束parent_fk外键 (parent_id) 引用parent(id) 开 更新时删除无操作无操作)
我假设这是因为尝试插入子项时父项未完全插入。
如果我不将子项添加到父项,则父项会很好地插入。 我尝试切换 GeneratedValue 生成策略,但没有帮助。
任何想法如何同时插入父母和孩子?
编辑:即使我先坚持父母,我仍然得到同样的错误。我确定这是因为 child 中没有设置 parent_id;孩子是默认构造的,因此 parent_id 设置为 0 不存在因此外键约束验证。
有没有办法让 jpa 自动设置分配给父实例的子代的 parent_id?
【问题讨论】:
-
如果这应该是单向关系,那么你为什么将
parentId放入Child实体中?外键存储在连接表中。 -
@ventsyv - 总结得恰到好处,孩子方面根本不需要那个id。
-
@Biraj Choudhury 我在 POJO 中不需要它,但我在表中确实需要它,所以我认为 JPA 需要“了解”它,以便将其设置为正确的价值。如果我将其从 POJO 中删除,则为插入子项而生成的查询未设置 parent_id 字段,因此将不起作用。
-
你说你需要一个单向关系,这意味着你有三个表 parent(parent Id - PK , ChildId- FK, 其他字段), child (Child Id - PK), parent_child ( Child Id - Parent一对多关系的 ID)。只有当您需要双向关系并且您可以通过@ManyToOne Parent parent 来实现时,您才需要 child 中的 parent id;除了这两种情况,你能告诉你想要实现什么吗?
-
@Biraj Choudhury 我有 2 张桌子 - 父母和孩子,其中孩子有 parent_id 标识父母。这是一对多的关系,一个父母可以有多个孩子,但每个孩子只有一个父母。我想归档(写入数据库)一个父对象列表,其中每个父对象都包含一个子对象列表。