Issue
Calling CrudRepository.save()
method deletes entry instead of updating the existing entry.
Controller:
@RequestMapping(value = "{id}", method = PATCH)
public User update(@PathVariable Long id, @RequestBody UpdateUser existingUser) {
return userService.update(existingUser);
}
Service:
public User update(UpdateUser existingUser) {
if (!userRepository.exists(existingUser.getId()) {
throw new UserNotFoundException();
}
UserEntity userEntity = existingUser.toEntity();
return userRepository.save(userEntity).toDto();
}
Dtos:
public User {
private Long id;
private String name;
// ..
public UserEntity toEntity() {
UserEntity entity = new UserEntity();
entity.setId(id);
entity.setName(name);
return entity;
}
}
public UpdateUser extends User {
@NotNull
@Override
public Long getId() {
super.getId();
}
}
I made sure that ID is set on the Dto as it's recieved by the controller & the service and that it's still the same after update. In any case what happens is that service update
method appears to save & delete the entity. Because I get back the dto which would have been created from entity returned from save
method and I can see the changed name. However if I refresh the page or look into the users
table the entry is gone.
Solution
You're always creating a new Entity and saving it (in your toEntity() method, which essentially overwrites the previous entity.
If you want to update an existing User, you need to do fetch + update on it's fields, and then invoke save.
for example this will update the name of an existing user:
UserEntity userEntity = userRepository.findOneById(existingUser.getId())
userEntity.setName(newName);
userRepository.save(userEntity);
You should also not set the ID of the entities by hand. Leverage @Id and @GeneratedValue.
Answered By - hovanessyan
Answer Checked By - Mildred Charles (JavaFixing Admin)