【问题标题】:updating table removes the data from columns which are not bound in jsp page更新表从jsp页面中未绑定的列中删除数据
【发布时间】:2015-03-12 20:17:42
【问题描述】:

我有一个有很多列的表。当我使用@ModelAttribute 更新某些列时,jsp 页面中未指定的列中的数据将被删除。

例子

@RequestMapping(value= "/studenteducation", method= RequestMethod.GET)
public String setupUpdateEducationForm(Model model, @ModelAttribute("education") Student student){

    student = studentService.getStudent(getStudentName());
    model.addAttribute("education", student);  //adding saved student data into model
    return "studenteducation";
}

@RequestMapping(value= "/studenteducation", method= RequestMethod.POST)
public String studentEducationForm(Model model, @ModelAttribute("education") Student student, BindingResult result){

    if(result.hasErrors()){
        return "studenteducation";          
    }

    student.setStudentId(getStudentName()); // inserting primary key
    studentService.updateStudent(student);  // updating student table

    return "redirect:/";        
}

问题是我没有绑定此更新中的所有列,因此只留下绑定的列数据,其他列数据从数据库中删除。我有 15 列,我在这个 jsp 页面中绑定了 5 列。

我的完整控制器代码:

@Controller
@RequestMapping("/user")
@SessionAttributes("education")
public class StudentController {

@Autowired
StudentService studentService;
Student student = new Student();

// Setup new Student form------------------------------------------------------------------ 

@RequestMapping(value= "/newuser", method= RequestMethod.GET)
public String setupAddStudentForm(Model model, @ModelAttribute("student") Student student){

    return "registerstudent";
}

// Add new Student------------------------------------------------------------------    

@RequestMapping(value= "/newuser", method= RequestMethod.POST)
public String sddStudent(Model model, @ModelAttribute("student") Student student, BindingResult result, SessionStatus sessionStatus){

    if(result.hasErrors()){
        return "registerstudent";
    }
    studentService.addStudent(student); 
    sessionStatus.setComplete();
    return "redirect:/";
}

// Setup Edit Profile Form------------------------------------------------------------------    

@RequestMapping(value= "/updateprofile", method= RequestMethod.GET)
public String setupStudentProfileForm(Model model, @ModelAttribute("profile") Student student ){

    Student stu = studentService.getStudent(getStudentName());
    model.addAttribute("name", student.getStudentId());
    model.addAttribute("studentprofile", stu);
    return "studentprofile";        
}

// Update student profile------------------------------------------------------------------ 

@RequestMapping(value= "/updateprofile", method= RequestMethod.POST)
public String studentProfileForm(Model model, @ModelAttribute("profile") Student student, BindingResult result, SessionStatus sessionStatus ){

    if(result.hasErrors()){
        return "studentprofile";            
    }

    student.setStudentId(getStudentName());
    studentService.updateStudent(student);      
    sessionStatus.setComplete();
    return "redirect:/";        
}

// Setup Update Education Form------------------------------------------------------------------    

@RequestMapping(value= "/studenteducation", method= RequestMethod.GET)
public String setupUpdateEducationForm(Model model, @ModelAttribute("education") Student student){

    student = studentService.getStudent(getStudentName());
    model.addAttribute("education", student);
    return "studenteducation";
}

// Update Student Education------------------------------------------------------------------   

@RequestMapping(value= "/studenteducation", method= RequestMethod.POST)
public String studentEducationForm(Model model, @ModelAttribute("education") Student student, BindingResult result, SessionStatus sessionStatus){

    if(result.hasErrors()){
        return "studenteducation";          
    }

    student.setStudentId(getStudentName());
    studentService.updateStudent(student);
    sessionStatus.setComplete();
    return "redirect:/";        
}

我的学生模型 id 很大,我正在通过 2 个控制器对其进行更新。不同jsp页面中的学生资料和具有不同控制器的不同jsp页面中的教育。当我更新一部分时,另一部分会删除。

【问题讨论】:

  • 桌上有触发器吗?
  • 不,它只是带有休眠注释@Entity 的简单表。
  • 有没有其他更好的方法来更新 hibernate 中的表。我正在使用 getSessionFactory.update(student)

标签: java hibernate jsp spring-mvc


【解决方案1】:

这是 Spring MVC 和 Hibernate 协同工作的方式。当您在控制器方法中编写 un@ModelAttribute("education") Student student 时,Spring MVC 会创建一个新对象并使用表单数据填充它。所有其他字段保持其初始化值(通常为空)。 你可能会觉得它很愚蠢,但我从来没有在 Spring MVC 中找到一个好的和干净的方法来处理它。常见的解决方法:

  • 按照 Neil McGuigan 的建议使用 SessionAttributes。问题是,当您不再需要该属性时,它可以保留在会话中,并且显然不能用于无会话 API 的使用。
  • 在 URL 中传递 id 并使用 Converter 将其转换为正确的 Student 对象。但是你必须在服务层之外调用持久层。

【讨论】:

  • 感谢您的回答。我只是采取了简单的方法。我将学生表拆分为 2 个不同的表,现在更新 jsp 页面中的完整列。所以它解决了我在已填充的未使用列中获取空值的问题。
【解决方案2】:

这就是@SessionAttributes 的用途

在控制器类声明的顶部添加@SessionAttributes("education")

在您的第一个方法中去掉@ModelAttribute("education") Student student 参数。改为使用该方法将学生添加到模型中。

在您的 POST 处理程序方法中添加一个 SessionStatus 参数,并在完成后调用 sessionStatus.setComplete()

您应该使用Post-Redirect-Get 模式。

如果用户不应该编辑此表单中的某些实体字段,您还应该使用 @InitBinder 设置不允许的字段:

@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
  dataBinder.setDisallowedFields("foo");
}

【讨论】:

  • 它给出了异常 org.springframework.web.HttpSessionRequiredException:预期的会话属性“教育”。我已经用新代码更新了问题请检查
  • 您可能需要使用@modelattribute METHOD 加载默认会话属性
  • 先生怎么样?我找不到这方面的任何例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多