blitzqwe
blitzqwe

Reputation: 2040

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?

Upvotes: 7

Views: 3778

Answers (3)

Neil McGuigan
Neil McGuigan

Reputation: 48256

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";
    }
}

Upvotes: 0

Ralph
Ralph

Reputation: 120831

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.

Upvotes: 3

Sebastien Lorber
Sebastien Lorber

Reputation: 92150

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

Upvotes: 0

Related Questions