【问题标题】:Deleting in a one to many unidirectional hibernate mapping删除一对多单向休眠映射
【发布时间】:2012-06-22 15:26:24
【问题描述】:

在单向休眠映射中删除父级的最佳做法是什么? (我正在使用 JPA)

Parent: 
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private List<Child> children= new ArrayList<Child>();

Child:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fk_parent")
private Parent parent;

孩子是这里关系的所有者,我想删除一个有孩子关联的父母。我如何实现它?我应该继续从父级中逐个迭代子级并删除它们,还是存在其他方式。不幸的是,在休眠文档中没有找到任何关于删除的内容。

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

    所以事实上,你的关联是双向的,而不是单向的......

    如果您的目标是在删除父级时删除子级,那么您只需要

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    private List<Child> children= new ArrayList<Child>();
    

    em.remove(parent);
    

    【讨论】:

    • 如果我现在有另一个父母,Parent1 与 Child 有相同的关系(就像 Parent 一样)。我可以删除 parent 而不必担心 child-parent1 之间的关系吗?
    • em.remove(parent) 在添加 Cascade 后不起作用,抛出“无法删除或更新父行:外键约束失败...”
    • 我收到此错误“外键约束失败......”与一对多双向一致并且无法通过它......我提供了所有 CascadeTypes 无济于事。
    • 哪个外键约束失败了?你确定你没有任何带有外键的行吗? Hibernate 执行的 SQL 查询有哪些?
    • 是的,我确实有一行 fk 给父母。我假设级联(cascade = CascadeType.ALL 或 REMOVE)在我执行 em.remove(parent) 时将删除所有子级。查看了hibernate执行的SQL查询,并没有为子行发出删除!令人惊讶的是,我确实看到为其他类型的孩子(与父母具有相同的一对多关系)发布了删除语句!为什么会这样?我没有发现映射其他子类的方式有什么不同。
    【解决方案2】:

    天哪!发现了问题。这与级联无关,但需要级联。问题在于我将孩子添加到父母并删除它们的方式。所以总结一下:

    如果我在父节点上执行保存以创建关联:

    parent.addChild(child)  
    em.save(parent)
    

    那么我必须在删除时从父级操作。或者,如果我将孩子添加为

    child.setParent(parent)
    em.save(child)
    

    然后我必须对孩子进行操作以删除它等等。

    【讨论】:

    • EntityManager 中没有 save() 方法。保存实体的方式(可能是几年前,并且可能使用 Hibernate 以外的其他东西)对您必须如何删除它没有任何影响。
    • 是的,我知道。它很奇怪,至少在我的环境中。但是,当我重新部署时,一切都开始工作了,我想所有的关联都会正确同步。 [将用持久性替换保存]
    猜你喜欢
    • 2013-05-23
    • 2016-12-31
    • 2011-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    相关资源
    最近更新 更多