0

i have a table which have many columns. When i update some of the columns using @ModelAttribute, the data from the columns which are not specified in jsp page is removed.

example

@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:/";        
}

the problem is that i am not binding all the columns in this update and thus only bound columns data is left and other columns data is removed from the database. I have like 15 columns and i am binding 5 columns in this jsp page.

My full Controller Code :

@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:/";        
}

My Student model id large and i am updating it by 2 controllers. Student profile in different jsp page and education in different jsp page with different controllers. When i update one portion the other portion deletes.

Kharoud
  • 307
  • 1
  • 7
  • 20

2 Answers2

1

This is what @SessionAttributes is for

Add @SessionAttributes("education") on top of your Controller class declaration

Get rid of the @ModelAttribute("education") Student student parameter in your first method. Add a student to the model in that method instead.

Add a SessionStatus parameter to your POST handler method and call sessionStatus.setComplete() when you're done.

You should be using the Post-Redirect-Get pattern.

You should also be using @InitBinder to set disallowed fields if users are not supposed to edit some entity fields in this form:

@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
  dataBinder.setDisallowedFields("foo");
}
Neil McGuigan
  • 46,580
  • 12
  • 123
  • 152
  • It is giving exception org.springframework.web.HttpSessionRequiredException: Expected session attribute 'education'. I have updated the question with new code plz check – Kharoud Mar 13 '15 at 06:39
  • You might need to load default sessionattributes with a @modelattribute METHOD – Neil McGuigan Mar 13 '15 at 07:13
  • how sir ? I could not find any examples on this. – Kharoud Mar 13 '15 at 07:20
  • see http://stackoverflow.com/questions/29039116/how-to-partially-update-record-with-spring-mvc-and-use-post-redirect-get-patte/29039117#29039117 – Neil McGuigan Mar 13 '15 at 18:20
1

It is the way Spring MVC and Hibernate work together. When you write in your controller method un @ModelAttribute("education") Student student, Spring MVC creates a new object and populates it with form data. All other fields keep their initialization values (generally null). You may find it stupid, but I have never found a nice and clean way to deal with that in Spring MVC. Common workarounds :

  • Use SessionAttributes as suggested by Neil McGuigan. The problem is that the attribute can stay in session when you no longer need it, and it cannot obviously be used for sessionless API usage.
  • pass the id in URL and use a Converter to convert it into the correct Student object. But you have to call the persistance layer outside the service layer.
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Thank you for the answer. I just took easy way out. I split my student table into 2 different tables and now updating full columns in jsp page. So it solved my problem of getting null values in already filled unused columns. – Kharoud Mar 13 '15 at 08:54