'Request Problem in Spring Boot through Postman and Swagger

I have a problem about sending the same request through Postman and Swagger in Spring Boot.

When I send a request through Postman, it is successfully sent without any issue. When I send a request through Swagger, I get an error with status 500. Then I open the console and this error message is shown like this.

org.hibernate.PersistentObjectException: detached entity passed to persist: com.refreshtokenjwt.app.modal.Role

Here is my User Entity.

@Entity
@Table(name = "Users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User extends IdBasedEntity implements Serializable {

    private String username;
    private String email;
    private String password;

    @ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinTable(name = "user_roles",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles = new HashSet<>();

}

Here is my Role Entity.

@Entity
@Table(name = "Roles")
@Data
@NoArgsConstructor
public class Role extends IdBasedEntity implements Serializable {

    @Enumerated(EnumType.STRING)
    @Column(length = 20)
    private ERole name;

    public Role(ERole name){
        this.name = name;
    }

    public ERole getName() {
        return name;
    }
}

Here is my requests shown below. I don't get any issue in first request. After I send second request , I get an error.

{
    "username" : "User1",
    "password" : "user1",
    "email" : "[email protected]",
    "roles" : [
        "ROLE_USER"
    ]
}

{
    "username" : "User2",
    "password" : "user2",
    "email" : "[email protected]",
    "roles" : [
        "ROLE_USER"
    ]
}

Here is my method defined in RestController.

@PostMapping("/signup")
    public ResponseEntity<?> registerUser(@RequestBody SignupRequest signUpRequest) {

        LOGGER.info("AuthController | registerUser is started");

        String username = signUpRequest.getUsername();
        String email = signUpRequest.getEmail();
        String password = signUpRequest.getPassword();
        Set<String> strRoles = signUpRequest.getRoles();
        Set<Role> roles = new HashSet<>();

        if(userService.existsByUsername(username)){
            return ResponseEntity.badRequest().body(new MessageResponse("Error: Username is already taken!"));
        }

        if(userService.existsByEmail(email)){
            return ResponseEntity.badRequest().body(new MessageResponse("Error: Email is already taken!"));
        }

        User user = new User();
        user.setEmail(email);
        user.setUsername(username);
        user.setPassword(encoder.encode(password));


        if (strRoles != null) {
            strRoles.forEach(role -> {
                LOGGER.info("AuthController | registerUser | role : " + role);
                switch (role) {
                    case "ROLE_ADMIN":

                        Role adminRole = null;

                        if(roleService.findByName(ERole.ROLE_ADMIN).isEmpty()){
                            adminRole = new Role(ERole.ROLE_ADMIN);
                        }else{
                            adminRole = roleService.findByName(ERole.ROLE_ADMIN)
                                        .orElseThrow(() -> new RoleException("Error: Admin Role is not found."));
                        }

                        roles.add(adminRole);
                        break;

                    case "ROLE_MODERATOR":

                        Role moderatorRole = null;

                        if(roleService.findByName(ERole.ROLE_MODERATOR).isEmpty()){
                            moderatorRole = new Role(ERole.ROLE_MODERATOR);
                        }else{
                            moderatorRole = roleService.findByName(ERole.ROLE_MODERATOR)
                                    .orElseThrow(() -> new RoleException("Error: Moderator Role is not found."));
                        }

                        roles.add(moderatorRole);

                        break;

                    default:

                        Role userRole = null;

                        if(roleService.findByName(ERole.ROLE_USER).isEmpty()){
                            userRole = new Role(ERole.ROLE_USER);
                        }else{
                            userRole = roleService.findByName(ERole.ROLE_USER)
                                    .orElseThrow(() -> new RoleException("Error: User Role is not found."));
                        }

                        roles.add(userRole);

                }

            });
        }else{

            Role userRole = new Role();
            userRole.setName(ERole.ROLE_USER);

            roles.add(userRole);
        }

        user.setRoles(roles);
        userService.saveUser(user);

        return ResponseEntity.ok(new MessageResponse("User registered successfully!"));
    }

Here is my SignUpRequest class shown below.

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SignupRequest {

    @NotBlank
    @Size(min = 3, max = 20)
    private String username;

    @NotBlank
    @Size(min = 6, max = 40)
    private String password;

    @NotBlank
    @Size(max = 50)
    @Email
    private String email;

    private Set<String> roles;

}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source