Reputation: 12268
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
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