ichoicerenderer needs an id and a display value, the converter only has a
single tostring - would that be used for id or for display value?
-igor
On 5/10/07, Dimitrio <[EMAIL PROTECTED]> wrote:
Thanks to everybody the replies!
I played with form components for awhile and in particular with
DropDownChoice and could get it to do exactly what I needed.
Just to remind -- I wanted to prevent the DropDownChoice from loading the
entire list of choices ( countries) on submit, but to only load the entity
selected by the user by some indexed unique field and assign it to the
object being edited ( city).
DropDownChoice loads the list of choices in the
AbstractSingleSelectChoice.convertValue(String[]) method which is final.
That method is called from FormComponent's convert() which is also final.
However, if a form component has been provided with a type, convertValue()
is not called, and instead a converter is used.
So, here is what I did:
1. Wrote a CountryConverter:
public class CountryConverter extends SimpleConverterAdapter {
public Object toObject(String value) {
return ServiceUtils.getAddressService().getCountryByCode(value);
}
public String toString(Object value) {
return String.valueOf(value);
}
}
Not sure about the purpose of toString method here. Initially I thought it
would be passed a Country instance and would return a String to be rendered
as the value for <option> (an ISO code), but it looks like an
IChoiceRenderer is used for this purpose. toString was being invoked with
String representations of my countries.
2. Wrote a CountryChoiceRenderer:
public class CountryChoiceRenderer implements IChoiceRenderer {
public String getIdValue(Object object, int index) {
Country country = (Country) object;
return country.getIsoCode();
}
public Object getDisplayValue(Object object) {
Country country = (Country) object;
return country.getName();
}
}
3. Implemented a DropDownChoice as an inner class of my panel:
class CountryChoice extends DropDownChoice {
public CountryChoice(String id) {
super(id);
setChoices(new LoadableDetachableModel() {
protected Object load() {
return ServiceUtils.getAddressService
().getAllCountries();
}
});
setRequired(true);
setChoiceRenderer(new CountryChoiceRenderer());
setType(Country.class);
}
public IConverter getConverter() {
return new CountryConverter();
}
}
Here is what happens on submit:
1. Form processing begins and eventually FormComponent.convert() is called
on my CountryChoice.
2. FormComponent.convert() sees that the component has a type (
Country.class) and instead of calling convertValue() calls my converter.
3. My converter selects a country by ISO code.
4. The City instance is assigned the selected country and then
saveOrUpdate()'d.
5. If I redisplay my panel, the country list will, of course, be loaded
during the rendering phase. If I redirect to some other page, the country
list will not be loaded -- just as I needed.
I would like to see some comments regarding this approach. What do you
think about it? Can you suggest any improvements? Would consider using it in
your Wicket application? Is it "the Wicket way" of doing things?
Best regards,
Dimitrio
On 5/9/07, Igor Vaynberg <[EMAIL PROTECTED]> wrote:
>
> there is wicket-phonebook project in wicket-stuff that shows
> wicket+spring+hibernate
>
> your dropdownchoice should use a loadable detachable model, that way the
> list is loaded once per request
>
> add(new dropdownchoice("city", new loadabledetachablemodel() { load() {
> return dao.listcities(); }}));
>
> that answers question 1 and question 2 - the data will be reloaded in
> onsubmit() since that is a new request, but that same data will be used for
> rendering as well.
>
> -igor
>
>
> On 5/9/07, Dimitrio <[EMAIL PROTECTED]> wrote:
>
> >
> > Hello All,
> >
> > I am evaluating the possibility to use the Wicket / Spring / Hibernate
> > stack for my next project (Spring / Hibernate being used for the middle tier
> > + OpenSessionInViewFilter).
> >
> > Let me describe a simple test scenario that I am trying to implement -
> > a City Editor panel. The panel contains a text field with a city name and a
> > drop down choice with the available countries.
> >
> > The domain model (mapped to the DB via Hibernate) is the following:
> >
> > City
> > ---------
> > Long id;
> > String name;
> >
> > @Cascade(SAVE_UPDATE)
> > Country country;
> >
> > Country
> > ------------
> > Long id;
> > String isoCode;
> > String name;
> >
> > Upon construction, the Country drop down choice for the panel is
> > provided with a LoadableDetachableModel that loads a list of all available
> > countries from a CountryDao. The form itself has a CompoundPropertyModel for
> > the city being edited.
> >
> > The page renders just fine, the country list is correctly reloaded
> > upon F5 - everything as expected.
> >
> > However, when the user clicks Submit, the form component reloads the
> > country list again (so the list ends up in the new Hibernate session cache)
> > and when I try to save the city in onSubmit, I sometimes get a
> > Hibernate exception with the following message:
> >
> > a different object with the same identifier value was already
> > associated with the session: [test.wicket.Country#6]; nested exception
> > is org.hibernate.NonUniqueObjectException: a different object with the
> > same identifier value was already associated with the session: [
> > test.wicket.Country#6]
> >
> > This exception only occurs if the user does not change the city's
> > country. In that case the Country instance referenced by the city is
> > different from the corresponding instance in Hibernate session cache and the
> > SAVE_UPDATE cascading fails.
> >
> > So, my first question is whether there is a way to avoid this
> > exception?
> >
> > The second thing is that I do not generally want all my reference data
> > being completely reloaded on every submit.
> >
> > I really liked the way property editors were used in Spring to
> > retrieve and validate reference data for such scenarios. In Spring I would
> > have a CountryPropertyEditor that would retrieve the Country instance by an
> > ISO code or ID and assign it to the city.
> >
> > So in Spring the submit would result in 2 statements like below:
> >
> > select from country where id=...
> > update city where id=...
> >
> > and avoid the duplicate instances problem altogether.
> >
> > So, the second question is whether there is a way to not reload all
> > the reference data upon submit? How do you address such scenarios in your
> > Wicket applications?
> >
> >
> > Many thanks!
> >
> > --Dimitrio
> >
> >
> >
> >
> > -------------------------------------------------------------------------
> > This SF.net email is sponsored by DB2 Express
> > Download DB2 Express C - the FREE version of DB2 express and take
> > control of your XML. No limits. Just data. Click to get it now.
> > http://sourceforge.net/powerbar/db2/
> > _______________________________________________
> > Wicket-user mailing list
> > Wicket-user@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/wicket-user
> >
> >
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Wicket-user mailing list
> Wicket-user@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/wicket-user
>
>
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Wicket-user mailing list
Wicket-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wicket-user