Aquí está mi estructura de entidad y tabla como se muestra a continuación.
@Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq") @SequenceGenerator(name = "seq", sequenceName = "user_data_seq") private Integer id; @Column(name = "FName") private String fname; @Column(name = "LName") Private String lname; CREATE TABLE user ( id integer NOT NULL DEFAULT nextval('user_data_seq'::regclass), fname character varying(32) COLLATE pg_catalog."default" NOT NULL,, lname character varying(32) COLLATE pg_catalog."default" NOT NULL CONSTRAINT pk_user PRIMARY KEY (id), CONSTRAINT user_fname_unique UNIQUE (fname) }He realizado una entrada manual en USUARIO a través de pgAdmin, se inserta con el último valor de secuencia.
INSERT INTO user(fname, lname) VALUES('AAA', 'BBB');Ahora la aplicación está usando e intentando actualizar el LName para el registro existente. Pero parece que JPA está considerando esto como una nueva entrada e intentando volver a insertar, debido a que se está produciendo un error de violación de restricción único.
public User updateLName(final User user) { User userToUpdate = userRepository.findById(user.getId()); userToUpdate.setLName("CCC"); userToUpdate = userRepository.save(userToUpdate); return userToUpdate; }El siguiente código (si es una condición) de Spring JPA, aún regresa como verdadero y crea el registro para insertarlo como NUEVO:
org.springframework.data.jpa.repository.support.SimpleJpaRepository @Transactional public <S extends T> S save(S entity) { if (this.entityInformation.isNew(entity)) { this.em.persist(entity); return entity; } else { return this.em.merge(entity); } }Pero esto no será un problema para los registros insertados a través de la aplicación que ya pueden actualizarse.
La identidad de las entidades se define por sus claves primarias. Por lo tanto, debe especificar qué datos desea actualizar. Para actualizar el método save() existente, puede obtener los datos existentes por id.
User userToUpdate = userRepository.getOne(id);La actualización de sus datos
userToUpdate.setFname(userDto.getFName());Y finalmente, llame al método de guardado para actualizar los datos en la base de datos.
userRepository.save(userToUpdate);