针对唯一字段顺序抛出 DataIntegrityViolationException,而不是同时抛出

问题描述 投票:0回答:1

我的 Spring Boot 应用程序遇到一个问题,其中针对唯一字段按顺序而不是同时抛出 DataIntegrityViolationException。尽管用户名和电子邮件字段都有独特的约束和 @Column(unique = true) 注释,但这种情况仍然发生。我仔细检查了一下,它们在 postgres 中也有独特的约束。

具体行为:

  1. 使用重复的用户名和电子邮件的请求:
  • 请求正文:
{
    "email": "[email protected]",
    "password": "test",
    "username": "test"
}

抛出异常:仅适用于电子邮件的 DataIntegrityViolationException。

  1. 请求更新电子邮件,重复用户名:
  • 请求正文:
{
    "email": "[email protected]",
    "password": "test",
    "username": "test"
}

抛出异常:用户名的 DataIntegrityViolationException;

预期行为:

我希望应用程序在第一个请求中同时针对两个违规字段(用户名和电子邮件)抛出 DataIntegrityViolationException,因为这两个字段都有唯一的约束。

这是我的文件:

控制器:

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/auth")
public class AuthenticationController {
    @Autowired
    private final AuthenticationService authenticationService;

    @PostMapping("/register")
    @Transactional
    public ResponseEntity<APIResponse<AuthenticationResponseDTO>> register(
            @Valid @RequestBody RegisterRequestDTO request
    ) {
        APIResponse<AuthenticationResponseDTO> response = authenticationService.register(request);
        return ResponseEntity.status(HttpStatus.valueOf(response.getHttpStatus())).body(response);
    }

}

服务:

@Service
@RequiredArgsConstructor
public class AuthenticationService {
    @Autowired
    private final UserRepository userRepository;

    @Autowired
    private final JwtTokenService jwtService;

    @Autowired
    private final PasswordEncoder passwordEncoder;

    @Transactional
    public APIResponse<AuthenticationResponseDTO> register(RegisterRequestDTO request) {
        var user = User.builder()
                       .email(request.getEmail())
                       .username(request.getUsername())
                       .password(passwordEncoder.encode(request.getPassword()))
                       .type(request.getUserType())
                       .build();

        var jwtToken = jwtService.generateToken(user);
        user.setAuthToken(jwtToken); 

        userRepository.saveAndFlush(user); //I've Placed the debugger here
        AuthenticationResponseDTO authenticationResponse = AuthenticationResponseDTO.builder()
                                                                                    .accessToken(jwtToken)
                                                                                    .build();
        return APIResponse.ok(authenticationResponse,
                              Constant.getUserResponseHashMap(),
                              Constant.USER_RESPONSE_CODE_PREFIX.concat("7")
        );
    }
}
java spring spring-boot spring-mvc jparepository
1个回答
0
投票

您必须为电子邮件和用户名字段添加一项唯一约束。例如:

@Entity
@Table(name = "users",
    uniqueConstraints = {
            @UniqueConstraint(columnNames = "username"),
            @UniqueConstraint(columnNames = "email")
    })
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class User {

  @Id
  @GeneratedValue(strategy= GenerationType.AUTO)
  private Long id;

  private String username;

  private String email;
  //...
}

@Column(unique=true)
用于为单个字段添加单个唯一约束,这就是它不起作用的原因。检查 this 了解有关在 JPA 中定义唯一约束的更多详细信息。

希望它能有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.