J'ai une entité avec 3 champs: id, nom et numéro de téléphone. Je veux créer une méthode qui fonctionne pour mettre à jour tous les champs ou seulement un ou deux.
J'utilise Hibernate et JPA Repository. Quand j'essaie de mettre à jour tous les champs, tout fonctionne bien mais quand, par exemple, je veux mettre à jour uniquement le nom de famille sans changer de phoneNumber, j'ai en sortie null insted de l'ancien phoneNumber.
Voici ma méthode de Controller: p>
@Entity @Table(name = "student") @DynamicUpdate public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; @Column(name = "email") private String email; //@OneToMany(mappedBy = "student") @ManyToMany @JoinTable(name="course_student",joinColumns = @JoinColumn(name="student_id"), inverseJoinColumns = @JoinColumn(name="course_id")) private List<Courses> courses; @OneToOne(cascade = CascadeType.ALL) // @JoinColumn(name="studen/_details_id") // with this we have dobule student_details column private StudentDetails studentDetails; public List<Courses> getCourses() { return courses; } public void setCourses(List<Courses> courses) { this.courses = courses; } public StudentDetails getStudentDetails() { return studentDetails; } public void setStudentDetails(StudentDetails studentDetails) { this.studentDetails = studentDetails; } // Methods for StudentViewController public String getLastname(){ return studentDetails.getLastname(); } public String getPhoneNumber(){ return studentDetails.getPhoneNumber(); } public Student() { } public Student(String name, String email, StudentDetails studentDetails) { // this.id = id; this.name = name; this.email = email; this.studentDetails = studentDetails; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", email='" + email + '\'' + '}'; } }
La classe pour la mise à jour:
@DynamicUpdate @Entity public class StudentDetails { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name="lastname") private String lastname; @Column(name="phone_number") private String phoneNumber; public StudentDetails() { } public StudentDetails(Long id, String lastname, String phoneNumber) { this.id = id; this.lastname = lastname; this.phoneNumber = phoneNumber; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } }
La classe qui a une relation avec StudentDetails:
@PutMapping("/students/update/{id}") public String updateStudentById(@ModelAttribute Student student, @ModelAttribute StudentDetails studentDetails, String lastname, String phoneNumber, @PathVariable Long id) { Optional<Student> resultOptional = studentRepository.findById(id); //Student result =resultOptional.get(); resultOptional.ifPresent((Student result) -> { result.getStudentDetails().setPhoneNumber(studentDetails.getPhoneNumber()); result.getStudentDetails().setLastname(studentDetails.getLastname()); studentRepository.save(result); }); return "Student updated"; }
3 Réponses :
pourquoi ne définissez-vous pas simplement les paramètres de votre requête dans vos setters?
resultOptional.ifPresent((Student result) -> { result.getStudentDetails().setPhoneNumber(phoneNumber); result.getStudentDetails().setLastname(lastname); studentRepository.save(result); });
Vous oubliez de définir le mappage @OneToOne dans StudentDetails - StudentDetails a également besoin d'un champ de type Student qui sera annoté @OneToOne.
Vous devez également vous assurer que tous les champs d'entité seront remplis - en savoir plus sur les types de récupération.
J'ai ajouté dans StudentDetalis.class: @OneToOne (fetch = FetchType.EAGER) étudiant privé; et dans Student.class: @OneToOne (cascade = CascadeType.ALL, fetch = FetchType.EAGER) private StudentDetails studentDetails; mais n'aide pas du tout.
Votre code fonctionne correctement. Lorsque vous ne fournissez que le paramètre Modifiez le code de la manière suivante: Malheureusement, cela pose un autre problème : Comment allez-vous supprimer ces champs? (Comment pouvez-vous les définir explicitement sur Une solution possible si vous vérifiez le Ce sera un code assez compliqué de toute façon ... Vous devriez envisager d'utiliser le package Spring Data Rest . Il crée automatiquement tous les points de terminaison REST standard pour vos entités et gère tous ces problèmes PUT / PATCH / POST / DELETE prêts à l'emploi. lastName
dans votre demande, le paramètre phoneNumber
sera mappé à null
afin que vous remplaciez le phoneNumer code> dans votre entité avec cette valeur
null
. resultOptional.ifPresent((Student result) -> {
if(studentDetails.getPhoneNumber()!=null) {
result.getStudentDetails().setPhoneNumber(studentDetails.getPhoneNumber());
}
if(studentDetails.getLastname()!=null) {
result.getStudentDetails().setLastname(studentDetails.getLastname());
}
studentRepository.save(result);
});
null
?) ""
(chaîne vide) et définissez la propriété à null
si le paramètre est une chaîne vide.
Merci beaucoup ! :)
essayez d'utiliser le modèle de sélection et de mise à jour
Jetez un œil à: stackoverflow.com/questions/39741102/...
Hé, je l'ai vérifié, mais toutes les solutions sont utiles.