Tengo una aplicación Spring y agregué a mi entidad de usuario restricciones únicas para el nombre de usuario y el correo electrónico. Por lo tanto, los usuarios no pueden crear muchas cuentas con el mismo nombre de usuario o correo electrónico. Cuando alguien crea un nuevo usuario con un nombre de usuario que ya existe, mi aplicación me lanza ConstraintViolationException
Mis detalles de excepción:
org.postgresql.util.PSQLException: ERROR: los valores de clave duplicados violan las restricciones únicas "ukdfui7gxngrgwn9ewee3ogtgym" Detalle: la clave (nombre de usuario) = (dev123) ya existe.
Mi entidad de usuario:
@Table(name = "usr", uniqueConstraints={ @UniqueConstraint(columnNames ={"username"}), @UniqueConstraint(columnNames={"email"})}) public class User { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="usr_seq") @SequenceGenerator(name = "usr_seq", sequenceName = "usr_seq", initialValue = 1, allocationSize=1) @Column(name="id") private Long id; @Column(name = "username") private String username; @Column(name = "password") private String password; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @Column(name = "role") private Role role; @Column(name = "email") private String email; @Column(name = "status") private Status status; // @OneToMany(mappedBy = "author") // private List<Message> messages; // @OneToMany(mappedBy = "author") // private List<Comment> comments; @OneToOne @JoinColumn(name = "gender_id") private Gender gender; @OneToOne @JoinColumn(name = "address_id") private Address address; @ManyToMany @JoinTable( name = "user_subscriptions", joinColumns = @JoinColumn(name = "channel_id") , inverseJoinColumns = @JoinColumn(name = "subscriber_id")) private Set<User> subscribers; @ManyToMany @JoinTable( name = "user_subscriptions", joinColumns = @JoinColumn(name = "subscriber_id") , inverseJoinColumns = @JoinColumn(name = "channel_id")) private Set<User> subscriptions; @OneToOne @JoinColumn(name = "file_id") private FileEntity fileEntity; }Mi tabla de usuario:
create table usr ( id bigint not null constraint usr_pkey primary key, email varchar(255) constraint ukg9l96r670qkidthshajdtxrqf unique, first_name varchar(255), last_name varchar(255), password varchar(255), role integer, status integer, username varchar(255) constraint ukdfui7gxngrgwn9ewee3ogtgym unique, address_id integer constraint fkilsqnqkb7dlk6s5gqedb6lk3r references address, file_id bigint constraint fkabswqn807logqymtak5wfktfr references file, gender_id integer constraint fkp89wdnbeu22hjl41g38rk8a1q references gender ); alter table usr owner to postgres;Traté de manejar esa excepción en la clase @RestControllerAdvice:
@ExceptionHandler(ConstraintViolationException.class) public ResponseEntity<Object> handleConstraintViolationException(){ ExceptionDetails exceptionDetails = new ExceptionDetails(Errors.ERROR9.getMessage(),timestamp); return new ResponseEntity<>(exceptionDetails,HttpStatus.FORBIDDEN); }Pero esto detecta todos los problemas con las restricciones (no la violación nula, la violación de la clave principal, etc.) y solo quiero detectar violaciones de restricciones específicas para mi nombre de usuario y correo electrónico.
Antes de guardar el usuario, puede verificar si el nombre de usuario dado ya existe o no. Si ya existe, no guarde al usuario y solicite ingresar otro nombre de usuario; de lo contrario, guarde al usuario.