2

The main question is, how to update just a few chosen fields from our form. I would like to give user choice which fields they want to update. For example, I have the form class:

public class UserRegistrationform {
    private Integer userId;
    @NotNull
    private String name;
    @NotNull
    private String surname;
    @Email
    @NotNull
    private String email;
    @NotNull
    private Integer genderId;
    @NotNull
    private Integer groupId;
    @NotNull
    private List<ContactInfoDto> contactsInfo;
    @NotNull
    private String userSecretkey;
    @NotNull
    private String password;
    @NotNull   
    private boolean enabled;
    @NotNull    
    private boolean resetPassword;

After that I'm setting fields in @Entity class User, and for example, if user want to change just their name and surname, I want to take the rest of the fields from the existing User, by findById() method and after that change a few fields and save the changed object to the database.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
mroma95
  • 97
  • 12
  • Does this answer your question? [How do I update an entity using spring-data-jpa?](https://stackoverflow.com/questions/11881479/how-do-i-update-an-entity-using-spring-data-jpa) – silentsudo Mar 13 '21 at 06:04
  • 1
    First of all the variables in this class have `@NotNull` means that they are required fields in your form so user will have to enter them all or else api would return bad request – Beshambher Chaukhwan Mar 13 '21 at 06:16
  • Unfortunetly no, because I have the same form to register user and i also want to use the same form to update user and the main problem is that when user is registering I need to reject null fields, but if he registered correctly and after that he want to update his few fields he can chose fields which he want to update – mroma95 Mar 13 '21 at 06:18
  • @BeshambherChaukhwan I know because like i wrote above I want to use the same form to register and update user values – mroma95 Mar 13 '21 at 06:23
  • But still it won't allow null values for all fields so you will have to take all values and then manually change the required fields separately one by one – Beshambher Chaukhwan Mar 13 '21 at 06:56
  • @BeshambherChaukhwan what do you mean about take all values and manually change it? What do you think about my idea to solve it, create new form look like actually form but without validation or with my custom validation where default value is the value from existing object (it's possible to do at all?) – mroma95 Mar 13 '21 at 07:31
  • Yes it's possible to do both the ways. Filling old data or creating new form class. Usually we fill old data in form and update all fields during save but since other fields have old data so they are not really changed – Beshambher Chaukhwan Mar 13 '21 at 07:53
  • @BeshambherChaukhwan can you explain what u mean when you wrote about take all values and then manually change the required fields separately one by one – mroma95 Mar 13 '21 at 11:48
  • Take all the data of UserRegistrationForm and update only few data in separate function after getting user data by id – Beshambher Chaukhwan Mar 13 '21 at 11:50
  • I added comment, if you can explain to me with an example, will be grateful – mroma95 Mar 13 '21 at 12:33
  • @BeshambherChaukhwan and obviously I don't know which fields user will choose to update – mroma95 Mar 13 '21 at 15:15

1 Answers1

0

@BeshambherChaukhwan ok, maybe will be easier where I will use example, so I have a controller when is method:

    @PostMapping(value = "{id}/updateuser")
    public ResponseDTO updateUser(@PathVariable int id, @RequestBody UserRegistrationform userForm, BindingResult bindingResult) {
        User user = userRepository.findById(id);
        if (user == null) {
            return ResponseDTO.of(Messages.Error_UserNotFound_MSG.getMessage(), ErrorCodes.NOT_FOUND);
        } else if (bindingResult.hasErrors()) {
           return ResponseDTO.of(bindingResult.getAllErrors().toString(), ErrorCodes.INVALID_FIELDS);
        }
        user.setName(userForm.getName);
        user.setSurname(userForm.getSurname);
        user.setEmail(userForm.getEmail);
        .
        .
        .
        userRepository.save(user);
        return ResponseDTO.of(Messages.SUCCESS_Update_MSG.getMessage());
        }

The problem is, like you noticed when in form someone miss few fields, and I will update right fields by null values

mroma95
  • 97
  • 12
  • And now if I using a UserRegistrationForm and user will not fill field i will have response with error because i have annotation that fields can't be null – mroma95 Mar 13 '21 at 12:45
  • No they would not be null because you are using `@NotNull` in UserRegistrationForm – Beshambher Chaukhwan Mar 13 '21 at 15:51
  • And even if you remove the `@NotNull` from fields then you will need to first check `if(userForm.getName()!=null)` then set them. This is the manual work I was talking about. You will only update the fields you want to and only those will be updated which are being set. Maybe you can also check if old value is equal new value or not but that will not make any difference because `User user = userRepository.findById(id);` will have the correct old data and its in your control to update what field at what time. – Beshambher Chaukhwan Mar 13 '21 at 15:55
  • Oh no, is any another way to do it? Because i know about manual set fieds and it is ok when i have for example 5 fields but when i wnt to update 30 from 80 fields it will be a lot of lines of code – mroma95 Mar 13 '21 at 16:09
  • 1
    In that case you will encapsulate the fields in different classes. I use different classes for different apis. And I have classes within classes like you can put first name and last name in one class and user role permission info in other class, user address related fields in other class and then use them in different apis. Using the same class for different scenarios is not good because you will be forced to do manual set fields. – Beshambher Chaukhwan Mar 13 '21 at 16:33
  • Thank you so much for response, you help me a lot – mroma95 Mar 13 '21 at 16:34