Your problem is due to your passing of an entirely new User
entity hence Hibernate cannot use a cached version that has been already fetched from database and decide which columns to update dynamically.
So, try to do the following to confirm the correct behaviour of @DynamicUpdate
;
In service;
@Transactional
public User save(User newUser) {
User currentUser = userRepository.get(newUser.getId());
// handle merging of updated columns onto currentUser manually or via some mapping tool
currentUser.setName(newUser.getName());
return userRepository.save(currentUser);
}
With the above logic, together with dynamic update annotation, you should be able to see the update of only name column, unless you have some audit enabled, or using @Version
'ed column.
If the updated columns are always same, then it is better to use updatable = false
for the columns that are not target for the update in their @Column
definitions, for using @DynamicUpdate
is very inefficient since it generates each sql anew, never utilizing cached sqls. But beware using this feature, since you will be unable to update these columns at all.
I don't recommend using @Query
unless you have a case where native JPA/Hibernate is insufficient, but if you have a use-case to update a target set of columns only, it is the best choice, and the most efficient.
If the updated columns are many and can vary greatly, either define a manual mapping logic between newUser
to the currentUser
, or utilize some mapping tools such as Orika
, I have a similar automated structure where hundreds of entities are patched through these mappers, allowing an extremely generic way to handle many CRUD operations.