简体   繁体   中英

Spring MVC - how not to lose field values when binding to a form partially

I want to make an update form for a bean X. This bean lets say it has fields A, B, C, D. In my form I want to update just fields A, B and let C and D untouched. Is there a way to bind bean X to the update form with just fields A and B, so that when i submit the form C and D won't be changed ?

I know i can add hidden fields for C and D but what if these are not primitive fields, they are other beans or collections.

I know another solution would be to create a XUpdateBean that will have only fields A and B and after form submit copy the fields from XUpdateBean to my X bean.

Is there another way to this update better in Spring 3 MVC?

You could have a command-Object/form-barking-Bean that contains only the fields you need.

In the controller you have to load the bean X, and need to update its fields with the one from the commandObject.

May you can also think of not having an extra class for the commandObject, instead use class BeanX. But of course you need two instances of BeanX, one for the commandObject and one for bean x.

The correct way, in my mind, especially when dealing with Optimistic Concurrency Control (@Version) is to store the model attribute in session temporarily.

@Controller
@SessionAttributes("x")
public class MyController {

    @Autowired
    private XRepository xRepository;

    @InitBinder
    void initBinder(WebDataBinder binder) {
        binder.setDisallowedFields("id", "c", "d"); 
    }

    @RequestMapping("/x/{id}")
    String myForm(@PathVariable("id") long id, Model model) {

        X x = xRepository.findOne(id);
        model.addAttribute("x", x);

        return "x-edit";
    }

    @RequestMapping(value="/x/{id}", method= RequestMethod.POST)
    String save(@PathVariable("id") long id, @ModelAttribute X x, SessionStatus sessionStatus) {

        xRepository.save(x);

        sessionStatus.setComplete();
        return "x-edit";
    }
}

Sorry i don't know SpringMVC so my answer may be wrong.

With another binding framework called Stripes, we usually "hydrate" the data before the binding. This means you first load the bean from the db, and only then you'll bind the A and B value to it! But it still has C and D original values since the bean comes from the DB (usually a JPA entity). Thus you don't need hidden C and D fields!

It seems possible with SpringMVC: Spring MVC 3.0: How do I bind to a persistent object

Notice that you could also load bind to a "non-DB bean" like you actually do, (so you'll have C and D fields empty i guess if you don't use hidden fields). Then you can simply load the bean you want to modify from the DB, and do a merge between the binded bean, and the db bean, of the fields you want (here, you'll merge only A and B so that the C and D fields in the DB bean won't be modified)

You can find some interesting stuff here about data binding. For me in some tricky cases, binding directly to DB objects can be dangerous: How to use a binding framework efficiently

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM