我的 Spring Boot 应用程序遇到一个问题,其中针对唯一字段按顺序而不是同时抛出 DataIntegrityViolationException。尽管用户名和电子邮件字段都有独特的约束和 @Column(unique = true) 注释,但这种情况仍然发生。我仔细检查了一下,它们在 postgres 中也有独特的约束。
具体行为:
{
"email": "[email protected]",
"password": "test",
"username": "test"
}
抛出异常:仅适用于电子邮件的 DataIntegrityViolationException。
{
"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")
);
}
}
您必须为电子邮件和用户名字段添加一项唯一约束。例如:
@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 中定义唯一约束的更多详细信息。
希望它能有所帮助。