1

Am trying to persist the user only if the incoming user object Does not exists in DB. The service returns an Optional by calling the findByEmail method in user repo. In my case, there is an exact user already present in DB and object is returned properly.

However, in my controller, when i do Optional.map(user).orElse(persistuser), the orElse part is executed.

My understanding is that when Optional.map returns an Optional and also the user is present, then orElse should return the user, instead of performing the persistuser operation.

Please help me with the issue.

Controller:

@PostMapping(path = "/addUser", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Response> addUser(@RequestBody User user){
        
        user = userService.checkIfUserExsits(user.getEmail())
                          .map(usr -> usr)
                          .orElse(userService.persistUser(user));
        
        return respHelpers.prepareSuccessResponse(user,"Processed");                                       
    }

Service:

public Optional<User> checkIfUserExsits(String email){      
    Optional<User> user = Optional.ofNullable(userRepo.findByEmail(email));     
    return user;
}

Repository:

@Repository
public interface UserRepo extends JpaRepository<User, UUID> {

    public User findByEmail(String email); 

}
sgc
  • 23
  • 1
  • 3

1 Answers1

4

orElse() is a method, and when you call that method, its argument gets evaluated before it's body is executed. Therefore userService.persistUser(user) is always executed.

You should use orElseGet:

    user = userService.checkIfUserExsits(user.getEmail())
                      .map(usr -> usr)
                      .orElseGet(() -> userService.persistUser(user));

This way, the lambda expression's body will only be executed if the Optional is empty.

Eran
  • 387,369
  • 54
  • 702
  • 768