Krystian Sikora
Krystian Sikora

Reputation: 12268

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

I have table Account that contains FK to another table.

Option 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.
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). If I find it in changePassword method instead, it works fine(no joins). Problem is, I need this entity in a controller for validation so making the same database call 2 times is pointless.

Option 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.

I think option 2 is probably better if it comes to performance but option 1 feels more jpa-like. Any suggestions appreciated.

Upvotes: 3

Views: 7042

Answers (1)

Nathan Hughes
Nathan Hughes

Reputation: 96444

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):

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.

You'd need to use select-before-update or optimistic locking with this. select-before-update might be worse-performing than updating all the fields.

Apparently this is implementation-specific and not part of JPA.

Upvotes: 3

Related Questions