Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用JPA存储库更新实体中的一个字段_Java_Spring_Spring Data Jpa - Fatal编程技术网

Java 如何使用JPA存储库更新实体中的一个字段

Java 如何使用JPA存储库更新实体中的一个字段,java,spring,spring-data-jpa,Java,Spring,Spring Data Jpa,我有3个字段的实体:id、lastname和phoneNumber。我想创建一个方法,用于更新所有字段或仅更新一个或两个字段 我使用Hibernate和JPA存储库。 当我尝试更新所有字段时,一切正常,但例如,当我只想更新lastname而不更改phoneNumber时,我在输出null中使用了旧phoneNumber 以下是我从控制器获得的方法: @PutMapping("/students/update/{id}") public String updateStudentById(@Mode

我有3个字段的实体:id、lastname和phoneNumber。我想创建一个方法,用于更新所有字段或仅更新一个或两个字段

我使用Hibernate和JPA存储库。 当我尝试更新所有字段时,一切正常,但例如,当我只想更新lastname而不更改phoneNumber时,我在输出null中使用了旧phoneNumber

以下是我从控制器获得的方法:

@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";
}
与StudentDetails相关的班级:

@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 + '\'' +
                '}';
    }

}
@实体
@表(name=“student”)
@动态铜日期
公立班学生{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@列(name=“name”)
私有字符串名称;
@列(name=“email”)
私人字符串电子邮件;
//@OneToMany(mappedBy=“学生”)
@许多
@JoinTable(name=“course\u student”,joinColumns=@JoinColumn(name=“student\u id”),
inverseJoinColumns=@JoinColumn(name=“course\u id”))
私人名单课程;
@OneToOne(级联=级联类型.ALL)
//@JoinColumn(name=“studen/\u details\u id”)//我们有了dobule student\u details列
私人学生详情学生详情;
公开课程名单{
返回课程;
}
公共课程(列出课程){
本课程=课程;
}
公共学生详细信息getStudentDetails(){
返回学生详细信息;
}
公共无效设置StudentDetails(StudentDetails StudentDetails){
this.studentDetails=studentDetails;
}
//StudentViewController的方法
公共字符串getLastname(){
return studentDetails.getLastname();
}
公共字符串getPhoneNumber(){
return studentDetails.getPhoneNumber();
}
公立学生(){
}
公共学生(字符串名称、字符串电子邮件、StudentDetails StudentDetails){
//this.id=id;
this.name=名称;
this.email=电子邮件;
this.studentDetails=studentDetails;
}
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共字符串getEmail(){
回复邮件;
}
公用电子邮件(字符串电子邮件){
this.email=电子邮件;
}
@凌驾
公共字符串toString(){
返回“学生{”+
“id=”+id+
“,name=”“+name+”\“””+
“,email='”+email+'\''+
'}';
}
}

我正在寻找解决方案,我添加了@DynamicUpdate,但它仍然不起作用。

为什么不在setters中设置请求的参数呢

resultOptional.ifPresent((Student result) -> {
result.getStudentDetails().setPhoneNumber(phoneNumber);
result.getStudentDetails().setLastname(lastname);
studentRepository.save(result);
});

您忘记了在StudentDetails中设置@OneToOne映射-StudentDetails还需要类型为Student的字段,该字段将被注释为@OneToOne


此外,您还必须确保所有实体字段都已填充-请阅读有关获取类型的更多信息。

您的代码工作正常。当您仅在请求中提供
lastName
参数时,
phoneNumber
参数将映射到
null
,因此您可以使用该
null
值覆盖实体中的
phoneNumer
属性

按以下方式更改代码:

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
?)

如果您检查
(空字符串)并将参数设置为空字符串,则可能的解决方案是将属性设置为
null

这将是一个相当混乱的代码无论如何


您应该考虑使用Spring Data REST包。它会自动为您的实体创建所有标准REST端点,并即时处理所有这些PUT/PATCH/POST/DELETE问题。

尝试使用选择和更新模式查看:嘿,我选中了它,但任何解决方案都有帮助。.我在StudentDetalis.class中添加了:@OneToOne(fetch=FetchType.EAGER)private Student;在Student.class中:@OneToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)private StudentDetails StudentDetails;但是没有任何帮助。非常感谢!:)
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);
});