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

时间:2014-11-05 16:13:32

标签: java spring hibernate jpa spring-data

我的表帐户包含FK到另一张表。

选项1:

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

这样,每当我调用save()时,都会进行连接以检索另一个表ID,然后是更新本身。
请注意,即使只更改密码,所有字段也会更新。
<登记/> 编辑:我发现正在进行连接,因为我将实体作为参数传递(existingAccount)。如果我在changePassword方法中找到它,它可以正常工作(没有连接)。问题是,我需要在控制器中对此实体进行验证,因此进行2次相同的数据库调用是没有意义的。

选项2:

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

这样,只执行@Query中的自定义更新。

我认为选项2可能更好,如果涉及到性能,但选项1感觉更像jpa。任何建议表示赞赏。

1 个答案:

答案 0 :(得分:2)

这两个都应该没问题。如果您想使用第一种方式,但要避免更新除密码以外的字段,您可以configure dynamic-update使用注释@DynamicUpdate(value=true)

  

dynamic-update(可选 - 默认为false):指定应在运行时生成UPDATE SQL,并且只能包含值已更改的列。

您需要使用select-before-update或乐观锁定。 select-before-update可能比更新所有字段的性能更差。

显然是this is implementation-specific and not part of JPA