Update data in database using spring boot

I'm trying to change password of current logged in user. Any idea, why is it adding another row with the same columns except password that has been changed? May be i'm using the wrong method?

There is my controller MainController.java

@RestController
public class MainController {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private MyUserDetailsService myUserDetailsService;

    @Autowired
    private JwtUtil jwtTokenUtil;

    // Change the password
    @RequestMapping(value = "/settings", method = RequestMethod.PUT)
    public String updatePassword(@AuthenticationPrincipal MyUserDetails myUserDetails,
                                       @RequestBody UserCredentialsPojo pojo,
                                       Users users) {
        return myUserDetailsService.changePassword(users, myUserDetails,
                                                    pojo.getNewPassword(), pojo.getNewPassword1(), pojo.getOldPassword());
    }

    // Authentication with jwt token
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception {
        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword())
            );
        } catch (BadCredentialsException e) {
            throw new Exception("Incorrect username and password", e);
        }

        final UserDetails userDetails = myUserDetailsService
                .loadUserByUsername(authenticationRequest.getUsername());

        final String jwt = jwtTokenUtil.generateToken(userDetails);

        return ResponseEntity.ok(new AuthenticationResponse(jwt));
    }
}

UsersEntity.java

@Entity
@Table(name = "users")
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @Column(name = "username", length = 255)
    private String username;

    @Column(name = "firstname", length = 255)
    private String firstname;

    @Column(name = "lastname", length = 255)
    private String lastname;

    @Column(name = "password", length = 255)
    private String password;

    @Column(name = "roles", length = 255)
    private String roles;

    @Column(name = "email", length = 255)
    private String email;

    @Column(name = "lastLoginDate", length = 255)
    private String lastLoginDate;

    @Column(name = "registrationDate", length = 255)
    private String registrationDate;

    @Column(name = "lastLoginIp", length = 255)
    private String lastLoginIp;

    @Column(name = "balance")
    private Integer balance;

    @Column(name = "status")
    private Integer status;

    @Column(name = "birthDate", length = 255)
    private String birthDate;

    @Column(name = "departmentId")
    private Integer departmentId;

    @Column(name = "facultyId")
    private Integer facultyId;

    @Column(name = "advisorId")
    private Integer advisorId;

    // Getters and setters without constructor..

Here is MyUserDetails that extends UserDetails MyUserDetails.java.

public class MyUserDetails implements UserDetails {
    private Integer id;
    private String username;
    private String firstname;
    private String lastname;
    private String password;
    private List<GrantedAuthority> authorities;
    private String email;
    private String lastLoginDate;
    private String registrationDate;
    private String lastLoginIp;
    private Integer balance;
    private Integer status;
    private String birthDate;
    private Integer departmentId;
    private Integer facultyId;
    private Integer advisorId;

    public MyUserDetails(Users user) {
        this.id = user.getId();
        this.username = user.getUsername();
        this.firstname = user.getFirstname();
        this.lastname = user.getLastname();
        this.password = user.getPassword();
        this.authorities = Arrays.stream(user.getRoles().split(","))
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
        this.email = user.getEmail();
        this.lastLoginDate = user.getLastLoginDate();
        this.registrationDate = user.getRegistrationDate();
        this.lastLoginIp = user.getLastLoginIp();
        this.balance = user.getBalance();
        this.status = user.getStatus();
        this.birthDate = user.getBirthDate();
        this.departmentId = user.getDepartmentId();
        this.facultyId = user.getFacultyId();
        this.advisorId = user.getAdvisorId();
    }

    public MyUserDetails() {
    }

    // Getters and setters..

UsersRepository.java

public interface UserRepository extends JpaRepository<Users, Integer> {
    Optional<Users> findByUsername(String username);
}

MyUserDetailsService.java

@Service
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    // Change user password
    public String changePassword(Users users, MyUserDetails myUserDetails, String newPassword, String newPassword1, String oldPassword) {
        if (oldPassword.equals(myUserDetails.getPassword())) {
            if (oldPassword.equals(newPassword)) {
                return "New password cannot be the same as the old";
            } else if (!newPassword.equals(newPassword1)) {
                return "Passwords mismatches";
            } else if (newPassword.length() < 8) {
                return "New password too short";
            } else if (!newPassword.matches(".*")) {
                return "New password must contain at least 1 number";
            } else {
                users.setFirstname(myUserDetails.getFirstname());
                users.setLastname(myUserDetails.getLastname());
                users.setPassword(newPassword);
                users.setRoles(String.valueOf(myUserDetails.getAuthorities()));
                users.setEmail(myUserDetails.getEmail());
                users.setLastLoginDate(myUserDetails.getLastLoginDate());
                users.setRegistrationDate(myUserDetails.getRegistrationDate());
                users.setLastLoginIp(myUserDetails.getLastLoginIp());
                users.setBalance(myUserDetails.getBalance());
                users.setStatus(myUserDetails.getStatus());
                users.setBirthDate(myUserDetails.getBirthDate());
                users.setFacultyId(myUserDetails.getFacultyId());
                users.setAdvisorId(myUserDetails.getAdvisorId());
                users.setUsername(myUserDetails.getUsername());
                users.setDepartmentId(myUserDetails.getDepartmentId());
                userRepository.save(users);
                return "Password has been successfully changed";
            }
        } else {
            return "Password is wrong";
        }
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Optional<Users> user = userRepository.findByUsername(username);

        user.orElseThrow(() -> new UsernameNotFoundException("Not found: " + username));

        return user.map(MyUserDetails::new).get();
    }
}

Users table

+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+
| id | firstname | lastname | password | roles     | email  | lastLoginDate | registrationDate | lastLoginIp | balance | status | birthDate | facultyId | advisorId | username | departmentId |
+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+
|  2 | damir     | esenov   | admin    | student   | damir  | NULL          | NULL             | NULL        |    NULL |   NULL | NULL      | 1         | 1         | admin    | 1            |
|  3 | rapkat    | baudunov | rapkat   | NULL      | rapkat | NULL          | NULL             | NULL        |    NULL |   NULL | NULL      | NULL      | NULL      | rapkat   | NULL         |
| 15 | damir     | esenov   | admin123 | [student] | damir  | NULL          | NULL             | NULL        |    NULL |   NULL | NULL      | 1         | 1         | admin    | 1            |
+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+

My request in PostMan (I've changed the request to PUT method) Postman

{
    "oldPassword":"admin",
    "newPassword":"admin123",
    "newPassword1":"admin123"
}

Upvotes: 0

Views: 2469

Answers (1)

Eklavya
Eklavya

Reputation: 18410

Since id for users is null so JPA treats as new user that why create a new row in database. So just set id of users inside else

users.setId(myUserDetails.getId());

Better solution:

You don't need to set all the field if you need only to change password. First get the user by id then set the password and save.

users = userRepository.findById(myUserDetails.getId()).get();
users.setPassword(newPassword);
userRepository.save(users);

Upvotes: 1

Related Questions