JPQL 更新查询以更新实体而不使用主键

Posted

技术标签:

【中文标题】JPQL 更新查询以更新实体而不使用主键【英文标题】:JQPL Update Query to update entity without using the primary key 【发布时间】:2014-06-17 12:12:32 【问题描述】:

这可能是一个简单的问题,但我试图找出是否有一种方法可以创建 JPQL 更新查询,该查询允许我使用唯一的列标识符更新单个持久实体,而不是主键。

假设我有如下实体:

@Entity
public class Customer 
    @ID
    private Long id;
    @Column
    private String uniqueExternalID;
    @Column
    private String firstname;
    ....

使用设置了 id 值的客户更新此实体很容易,但是,id 喜欢使用 uniqueExternalId 更新此客户实体,而无需预先查询本地实体并将更改合并或手动构建 jpql手动查询其中的所有字段。

类似

UPDATE Customer c SET c = :customer WHERE c.uniqueExternalId = :externalId

在 JQPL 中这样的事情可能吗?

【问题讨论】:

【参考方案1】:

您无法以您描述的确切方式执行此操作 - 通过传递实体引用,但您可以使用批量查询来实现相同的效果。

UPDATE Customer c SET c.name = :name WHERE c.uniqueExternalId = :externalId

请注意,您必须明确定义每个更新的属性。

请务必注意,批量查询会绕过持久性上下文。在持久性上下文中管理的实体实例不会反映对由批量更新更改的记录的更改。此外,如果您使用乐观锁定,请考虑使用批量更新增加实体的 @Version 字段:

 UPDATE Customer c SET c.name = :name, c.version = c.version + 1  WHERE c.uniqueExternalId = :externalId

编辑:JPA 2.0 规范在第 4.10 节中建议:

一般来说,应该只执行批量更新和删除操作 在新的持久性上下文中的事务中或在获取之前 或访问其状态可能受此类影响的实体 操作。

【讨论】:

+1 指出批量更新绕过持久性上下文和乐观锁定检查。

以上是关于JPQL 更新查询以更新实体而不使用主键的主要内容,如果未能解决你的问题,请参考以下文章

JPQL 更新查询如何处理@Version 字段?

JPA JPQL简介

JPQL 到 SQL 使用 Hibernate 更新查询交叉连接问题

在 JPQL 查询中执行更新/删除查询

更新同一张表的 JPQL 查询的性能改进

使用 JPQL 通过连接表进行查询时出错