【问题标题】:Why do JPA-generated update queries include more fields than necessary?为什么 JPA 生成的更新查询包含比必要更多的字段?
【发布时间】:2012-03-24 00:50:13
【问题描述】:

这可能是一个非常愚蠢的问题,但是……

我正在将 JPA 2.0 与 Hibernate 4 一起使用。我有一个包含许多字段的持久对象。

我在一个事务中创建并持久化它。然后,在另一个中,我查看该对象并更改其上一个字段的值:

try{
    tx.begin();
    MyObj object = myObjDAO.findById(objectId);
    object.setFieldA("Different value");
} finally {
    tx.commit();
}

JPA 在事务提交时会保留此更改,但我可以从我的 MySQL genquery.log 中看到它生成的更新语句涉及对象上的所有字段:

439 查询
/* update uk.co.core.objects.MyObj */ update myobj set created='2012-03-06 13:39:37', modified='2012-03-06 13:39:37', version=1 , fieldA='不同值', fieldB='originalValue', fieldC='originalValue' where id='objectId' and version=0; 439 查询提交

为什么它在查询中包含所有未更改的字段及其现有值,而不仅仅是:

update myobj set fieldA='different value', version=1, modified='somedate' where id='objectId' and version=0;

在这个示例中看起来可能没有太大区别,但我有一些具有更多字段的对象,所有这些都包含在它们的更新语句中。

即使纯粹从字符串数据量的角度来看,在更新查询中只包含更改的字段,难道不是更快/更有效吗?如果是这样,是否有配置选项可以做到这一点?

希望您能提供帮助,谢谢!

【问题讨论】:

    标签: sql hibernate jpa-2.0


    【解决方案1】:

    现在发现在同一个问题中问 2 个问题的危险。 ManuPK 和 Perception 都给出了很好的、有用的、正确的答案。但是我从 ManuPk 那里得到了更多的信息和理解,因此我接受了它。

    完全同意他的观点——设置属性应该只对某些表进行,性能肯定要前后测试。

    以后,我会尽量让我的问题更有针对性。

    【讨论】:

      【解决方案2】:

      您可以将休眠配置为排除更新查询中未修改的字段,如 article 中所述。

      这是通过在您的类映射中添加 dynamic-update="true" 来完成的。

      <class ... table="your_table" .... dynamic-update="true">
      

      在多列(遗留设计)或包含大量数据的大表中,这将对系统性能产生很大影响。

      正如here 所说,它可能会对性能产生一些影响。因此,在实施之前测量代码的性能。

      阅读 API here 了解更多信息。

      【讨论】:

        【解决方案3】:

        要仅保留增量,您的 ORM 必须:

        1. 读取对象的当前版本及其所有子实体, 来自数据库。
        2. 迭代每个属性并比较它们的值,看看它是否有 改变了。
        3. 生成专门的查询,仅用于更新属性 已更改。

        这比仅仅发布跨所有列的标准更新要复杂得多,而且由于复杂性增加,性能也会大大降低

        【讨论】:

        • 一个专门的 HQL 是一个好主意,当您确切地知道要更新什么时,无论版本如何。但恐怕您的解决方案可能是性能开销,因为对象必须加载到内存然后应该进行比较
        猜你喜欢
        • 1970-01-01
        • 2019-03-28
        • 2012-04-15
        • 1970-01-01
        • 2021-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多