【问题标题】:Hibernate Batch Update休眠批量更新
【发布时间】:2012-10-02 11:03:30
【问题描述】:

我正在尝试更新 Java 实体的集合,但 Hibernate 执行批量更新的顺序会导致违反约束的异常。 我会用下面的例子来说明情况。

实体学生 内部编号 字符串名称 字符串deskID

规则:2名学生不能同桌

第一次交易:插入 2 个学生如下 学生 1 编号:1 名称:ABC DeskId:D1

学生 2 编号:2 名称:DEF DeskId:D2

在此之后,我决定更新两个学生实体以交换他们的课桌 我将一组更新的学生实体发送到休眠更新 学生 1 编号:1 名称:ABC DeskId:D2

学生 2 编号:2 名称:DEF DeskId:D1

但这会导致违反约束异常,因为我认为更新一次只发生一条记录。

我正在使用 JTA 实体管理器来管理事务。我要更新的代码如下所示

updateMultiple(Collection<Student> updatedStudents)
        for (final Student student: updatedStudents)
        {
            final Student st= this.entityManager.getReference(Student.class, Student.getId());
            student.merge(st);
        }
        this.entityManager.flush();
        return breakClauseDtos;

【问题讨论】:

    标签: hibernate jakarta-ee jta hibernate-entitymanager batch-updates


    【解决方案1】:

    问题的根源很明确:数据库在执行 SQL 语句时而不是在提交时检查约束。执行第一条 SQL 语句时,违反了约束。

    您可以先将课桌从学生 1 移走,然后将其分配给学生 2,然后再将其说明交给学生 1,从而解决这个问题。这意味着三个 SQL 语句(超过必要的一个),然后您可能必须在每次更新后刷新会话(Hibernate 重新排序 SQL 语句,这可能会干扰您的手动排序)。

    但更好的解决方案是纠正数据模型中的问题。

    如果每张课桌只能由一个学生拥有,则课桌与学生之间存在 n:1 关系。 Desk 需要学生的 id 作为外键。不需要定义额外的约束。现在换课桌就是换课桌记录里的学生证。只需两个更新语句即可完成此操作。

    【讨论】:

    • 感谢您的回复,其实我的数据模型比这个复杂。代表我的问题的一个很好的例子是..一个学生有 2 个属性开始日期和结束日期,我对数据库有一个限制,说没有 2 个学生应该有重叠的开始日期和结束日期......这意味着我们不能有开始日期:1 和结束日期:4 的学生和开始日期:2 和结束日期:6 的另一个学生
    猜你喜欢
    • 2011-12-04
    • 1970-01-01
    • 2014-10-07
    • 2015-08-03
    • 1970-01-01
    • 2015-09-08
    • 2014-06-10
    • 1970-01-01
    • 2011-12-07
    相关资源
    最近更新 更多