【问题标题】:What is the best way to update the entity in JPA在 JPA 中更新实体的最佳方法是什么
【发布时间】:2012-01-08 14:30:56
【问题描述】:

我正在使用 JPA 进行一些 CRUD 操作。更新对象是正确的方法吗?

通过更新查询或者通过EntityManagerfind方法?
我有一个需要更新的Employee 对象。哪个是正确的方法?

请指导我。

【问题讨论】:

    标签: java jpa entitymanager


    【解决方案1】:

    Query API 上使用executeUpdate() 更快,因为它绕过了持久化上下文。但是,绕过持久化上下文会导致内存中的实例状态和数据库中该记录的实际值不是同步。

    考虑以下示例:

     Employee employee= (Employee)entityManager.find(Employee.class , 1);
     entityManager
         .createQuery("update Employee set name = \'xxxx\' where id=1")
         .executeUpdate();
    

    刷新后,数据库中的名称更新为新值,但内存中的员工实例仍保持原始值。您必须调用entityManager.refresh(employee)将更新后的名称从数据库重新加载到员工实例。如果您的代码在刷新后仍然必须操作员工实例,但您忘记刷新()员工实例,因为员工实例仍然包含原始值,这听起来很奇怪。

    通常,executeUpdate() 用于批量更新过程,因为它绕过持久性上下文而更快

    更新实体的正确方法是您只需通过设置器设置要更新的属性,并让 JPA 在刷新期间为您生成更新 SQL,而不是手动编写它。

       Employee employee= (Employee)entityManager.find(Employee.class ,1);
       employee.setName("Updated Name");
    

    【讨论】:

    • @Ken Chan、entityManager.find(Employee.class, 1)employee.setName("updated Name) 导致两个查询:选择和更新。如果我们在更新实体时只想要一个查询怎么办?有可能吗?
    • 我讨厌在 JPA 中进行更新的方式。它可能会导致许多意外更新和副作用。有时你甚至不知道自己正在更新。
    • 有什么方法可以用新对象更新所有属性而不是一个一个地做?
    • 如何创建EntityManager的实例?
    • @YeshwantKAKAD:您可以在存储库中自动装配 entityManager
    【解决方案2】:

    这取决于您想要做什么,但正如您所说,使用find() 获取实体引用然后仅更新该实体是最简单的方法。

    除非您有强烈的迹象表明这确实很重要,否则我不会担心各种方法的性能差异。

    【讨论】:

    • 我们可以使用 find() 获取 obj aObj 然后使用 aObj = new MyObj(//...) 更新对象吗?我在任何地方都没有看到这样的例子
    【解决方案3】:

    这取决于要更新的​​实体数量,如果您有大量实体使用 JPA 查询更新语句更好,因为您不必从数据库中加载所有实体,如果您只更新一个实体然后使用查找和更新就可以了。

    【讨论】:

    • 在批量更新的情况下。但这也打破了代码和数据库之间的隔离——JPA 的最大优势
    • 是的,但是在某些情况下您无法获取所有记录然后更新它们,这不是给定上下文中可接受的解决方案,因此它的使用取决于上下文。另外,当我说更新查询时,我的意思是“JPA 更新查询”而不是“SQL 更新查询”,所以您仍然几乎独立于数据库。
    • JPA 更新查询被转换为 SQL 查询 - 它仍然破坏了对象抽象。但也有合法的用例
    猜你喜欢
    • 2019-12-24
    • 2013-12-03
    • 1970-01-01
    • 2020-01-14
    • 2011-03-31
    • 2019-01-30
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多