简体   繁体   English

使用Spring Data JPA更新实体的正确方法是什么?

[英]What is the proper way of updating entity using Spring Data JPA?

I have table Account that contains FK to another table. 我有一个表帐户包含FK到另一个表。

Option 1: 选项1:

@Override
@Transactional(readOnly = false)
public Account changePassword(Account existingAccount, String newPassword){
    existingAccount.setPassword(newPassword);
    return accountDAO.save(existingAccount);
}

This way, whenever I call save(), a join is made to retrieve another tables ID, THEN the update itself. 这样,每当我调用save()时,都会进行连接以检索另一个表ID,然后更新自身。
Note that all fields are updated here even tho only password changes. 请注意,即使只更改密码,此处也会更新所有字段。

EDIT : I figured out that the join is being made because I'm passing entity as a parameter (existingAccount). 编辑:我发现正在进行连接是因为我将实体作为参数传递(existingAccount)。 If I find it in changePassword method instead, it works fine(no joins). 如果我在changePassword方法中找到它,它可以正常工作(没有连接)。 Problem is, I need this entity in a controller for validation so making the same database call 2 times is pointless. 问题是,我需要在控制器中使用此实体进行验证,因此进行2次相同的数据库调用是没有意义的。

Option 2: 选项2:

@Modifying
@Query("UPDATE Account SET password=(:pass) WHERE username=(:username)")
public void changePassword(@Param("username")String username, @Param("pass")String pass);

This way, only the custom update within @Query is executed. 这样,只执行@Query中的自定义更新。

I think option 2 is probably better if it comes to performance but option 1 feels more jpa-like. 我认为选项2可能更好,如果涉及到性能,但选项1感觉更像jpa。 Any suggestions appreciated. 任何建议赞赏。

Both of these should be ok. 这两个都应该没问题。 If you want to use the first way but avoid updating fields besides password you can configure dynamic-update with the annotation @DynamicUpdate(value=true) : 如果您想使用第一种方法但避免更新除密码之外的字段,您可以使用注释@DynamicUpdate(value=true) 配置动态更新

dynamic-update (optional - defaults to false): specifies that UPDATE SQL should be generated at runtime and can contain only those columns whose values have changed. dynamic-update(可选 - 默认为false):指定应在运行时生成UPDATE SQL,并且只能包含值已更改的列。

You'd need to use select-before-update or optimistic locking with this. 您需要使用select-before-update或乐观锁定。 select-before-update might be worse-performing than updating all the fields. select-before-update可能比更新所有字段的性能更差。

Apparently this is implementation-specific and not part of JPA . 显然这是特定于实现的,而不是JPA的一部分

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM