开发者

Spring MVC 3.0: How do I bind to a persistent object

I'm working with Spring MVC and I'd like it to bind a a persistent object from the database, but I cannot figure out how I can set my code to make a call to the DB before binding. For example, I'm trying to update a "BenefitType" object to the database, however, I want it to get the object fromthe database, not create a new one so I do not开发者_高级运维 have to update all the fields.

    @RequestMapping("/save")
public String save(@ModelAttribute("item") BenefitType benefitType, BindingResult result)
{
    ...check for errors
    ...save, etc.
}


There are several options:

  • In the simpliest case when your object has only simple properties you can bind all its properties to the form fields (hidden if necessary), and get a fully bound object after submit. Complex properties also can be bound to the form fields using PropertyEditors.

  • You may also use session to store your object between GET and POST requests. Spring 3 faciliates this approach with @SessionAttributes annotation (from the Petclinic sample):

    @Controller
    @RequestMapping("/owners/*/pets/{petId}/edit")
    @SessionAttributes("pet") // Specify attributes to be stored in the session       
    public class EditPetForm {    
        ...
        @InitBinder
        public void setAllowedFields(WebDataBinder dataBinder) {
            // Disallow binding of sensitive fields - user can't override 
            // values from the session
            dataBinder.setDisallowedFields("id");
        }
        @RequestMapping(method = RequestMethod.GET)
        public String setupForm(@PathVariable("petId") int petId, Model model) {
            Pet pet = this.clinic.loadPet(petId);
            model.addAttribute("pet", pet); // Put attribute into session
            return "pets/form";
        }
        @RequestMapping(method = { RequestMethod.PUT, RequestMethod.POST })
        public String processSubmit(@ModelAttribute("pet") Pet pet, 
            BindingResult result, SessionStatus status) {
            new PetValidator().validate(pet, result);
            if (result.hasErrors()) {
                return "pets/form";
            } else {
                this.clinic.storePet(pet);
                // Clean the session attribute after successful submit
                status.setComplete();
                return "redirect:/owners/" + pet.getOwner().getId();
            }
        }
    }
    

    However this approach may cause problems if several instances of the form are open simultaneously in the same session.

  • So, the most reliable approach for the complex cases is to create a separate object for storing form fields and merge changes from that object into persistent object manually.


So I ended up resolving this by annotating a method with a @ModelAttribute of the same name in the class. Spring builds the model first before executing the request mapping:

@ModelAttribute("item")
BenefitType getBenefitType(@RequestParam("id") String id) {
    // return benefit type
}


While it is possible that your domain model is so simple that you can bind UI objects directly to data model objects, it is more likely that this is not so, in which case I would highly recommend you design a class specifically for form binding, then translate between it and domain objects in your controller.


I'm a little confused. I think you're actually talking about an update workflow?

You need two @RequestMappings, one for GET and one for POST:

@RequestMapping(value="/update/{id}", method=RequestMethod.GET)
public String getSave(ModelMap model, @PathVariable Long id)
{
    model.putAttribute("item", benefitDao.findById(id));
    return "view";
}

then on the POST actually update the field.

In you example above, your @ModelAttribute should already be populated with a method like the above method, and the properties be bound using something like JSTL or Spring tabglibs in conjunction with the form backing object.

You may also want to look at InitBinder depending on your use case.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜