Search code examples
javaformshibernatewicketdropdownchoice

Wicket - form components losing reference when PropertyModel is updated


I have a form with some fields and DropdownChoices. One of them is filled dynamically: when the State is filled, City dropdown is updated, and that's ok until here.

Dropdowns filled dynamically (I'm using hibernate as ORM):

// in my form constructor
// umf is my model
umf = new Umf();

DropDownChoice stateChoice = new DropDownChoice<State>(
    "states",
    new PropertyModel(umf, "state"),
    em.createQuery("from State e").getResultList(),
    new ChoiceRenderer<State>("name")
);

DropDownChoice citiesChoice = new DropDownChoice<City>(
    "cities",
    new PropertyModel(umf, "city"),
    new ArrayList<City>(),
    new ChoiceRenderer<>("name")
);

The problem occurs after the first form submission (that occurs okay), when I try to clear form and my model to let form ready for other submission.

First problem is in onSubmit method, after persisting the object on database, I set a new object to my model: umf = new Umf(); in order to get ready to persist a new umf. After this the components appear to lose the umf reference.

The line that defines dropdown State model: new PropertyModel(umf, "state") not works anymore because even I changing the State in the dropdown, umf.state PropertyModel is not updated (always 0), consequently cities dropdown is not filled.

// right after statesChoice and citiesChoice declaration

statesChoice.add(new AjaxFormComponentUpdatingBehavior("change") {
    @Override
    protected void onUpdate(AjaxRequestTarget target) {
        citiesChoice.setChoices(
            em.createQuery("from City m where m.state.id = :state_id")
            .setParameter("state_id", umf.getState().getId())
            .getResultList()
        );
        target.add(cititesChoice);
    }
});

Is like that Wicket works? If the property model reference of components receives a new object, components loses it's reference and needs explicitly to be reset?


Solution

  • Change new PropertyModel(umf, "state") with new PropertyModel(form.getModel(), "umf.state"). Same for city.

    The problem you face is that once you pass umf to PropertyModel it is saved inside it as its own member field. Later you change the reference in the Form but the PropertyModel still points to its member field, the old one.

    By passing the model of the form it becomes dynamic - everytime the PropertyModel needs the states it will ask form's model for its modelObject.