Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic Put (Update) on Spring Boot

I want something very basic.

I just want to update the User. Front end sends a json for the user. I wanted to avoid set every value of currentUser (it has like 50 fields)

@PutMapping("user/{id}")
public boolean updateUser(@PathVariable id, @RequestBody User user) {
   User currentUser = userRepo.findOne(id);
   // What now??

}
like image 279
user10302013 Avatar asked Nov 19 '25 07:11

user10302013


2 Answers

you need to do something like that. Please keep in mind that this approach is helpful for partial object update. That means if your object(in RequestBody) doesn't contains some fields(field==null) then this field will remain unchanged.

@PutMapping("user/{id}")
public boolean updateUser(@PathVariable id, @RequestBody User user) {
   User currentUser = userRepo.findOne(id);
   user = (User) PersistenceUtils.partialUpdate(currentUser, user);
   return userRepo.save(user);

}

public class PersistenceUtils {

    public static Object partialUpdate(Object dbObject, Object partialUpdateObject){
        String[] ignoredProperties = getNullPropertyNames(partialUpdateObject);
        BeanUtils.copyProperties(partialUpdateObject, dbObject, ignoredProperties);
        return dbObject;
    }

    private static String[] getNullPropertyNames(Object object) {
        final BeanWrapper wrappedSource = new BeanWrapperImpl(object);
        return Stream.of(wrappedSource.getPropertyDescriptors())
                .map(FeatureDescriptor::getName)
                .filter(propertyName -> wrappedSource.getPropertyValue(propertyName) == null)
                .toArray(String[]::new);
    }


}
like image 194
Alexander Petrov Avatar answered Nov 21 '25 21:11

Alexander Petrov


First Approach:

  • If User type it sent from the front-end you don't need to set everything again, you can use the object itself to update the values.

So, you can take these steps:

  1. remove {id} from url mapping as id already included in User class
  2. check if id has a value, otherwise throw an execption that updating not possible
  3. if id is available just execute userRepository.save(user) for updating
  4. return body back to front

    @PutMapping("/user")
    public ResponseEntity < User > updateUser(@RequestBody User user) throws 
    URISyntaxException {
        log.debug("REST request to update User : {}", user);
        if (user.getId() == null) {
            throw new ResourceNotFoundException("User id should not be null ")
        }
        User result = userRepository.save(user);
        return ResponseEntity.ok().body(result);
    }
    

And here is the custom Exception definition when id is null:

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }

    public ResourceNotFoundException(String message, Throwable cause) {
        super(message, cause);
    }
}

Second Approach:

  • If you are still insisting to set huge amount of properties you can use org.springframework.beans.BeanUtils copyProperties as BeanUtils.copyProperties(sourceItem, targetItem)
@PutMapping("/{id}")
public ResponseEntity<User> update(@PathVariable("id") id,  @RequestBody User user) {
    User currentUser = userRepo.findOne(id);
    BeanUtils.copyProperties(user, currentUser);
    return ResponseEntity.ok(repo.save(targetItem));
}
like image 36
MohammadReza Alagheband Avatar answered Nov 21 '25 22:11

MohammadReza Alagheband



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!