wait, wait, do you actually do something like
new TextField<String>("name", new IModel<String>(){
public String getObject() {
return entity.getName();
}
public void setObject(String value) {
entity.setName(value);
}
public void detach(){}
});
for every single field in your system, or you use LazyModel?
Well, I've been trying to use LazyModel, but with it I have to pass the
type of every field (the last arg of TextField's constructor) because if I
don't, this exception is thrown:
Caused by: java.lang.IllegalArgumentException: T is not a class or
parameterizedType
at org.wicketstuff.lazymodel.reflect.Generics.getClass(Generics.java:78)
at org.wicketstuff.lazymodel.LazyModel.getObjectType(LazyModel.java:139)
at org.wicketstuff.lazymodel.LazyModel.getObjectClass(LazyModel.java:124)
at org.apache.wicket.markup.html.form.AbstractTextComponent.getModelType(
AbstractTextComponent.java:167)
at org.apache.wicket.markup.html.form.AbstractTextComponent.resolveType(
AbstractTextComponent.java:152)
at org.apache.wicket.markup.html.form.AbstractTextComponent.onBeforeRender(
AbstractTextComponent.java:142)
Any thoughts?
I guess I'll just go back to CompoundPropertyModel... (sigh)
(and no, I don't spend that much time debugging property models. I usually
don't rename properties that often, and when I have to do some refactoring,
usually the structure changes, and I have to revise all pages anyway...)
On Fri, May 31, 2013 at 10:49 AM, Martin Grigorov <[email protected]>wrote:
> On Fri, May 31, 2013 at 4:24 PM, tetsuo <[email protected]> wrote:
>
> > Black magic, or code generation? hard choice... :)
> > I think I'll try the black magic, let's see how it goes :)
> >
>
> I personally prefer writing the boilerplate of custom Model per field.
> It is a boring work but it gives me:
> * type safety
> * the fastest read/write access possible
> * easier debugging
>
> (who knows - maybe I've spent less time to write such models than you've
> spent to debug your issues with property model after refactoring)
>
>
>
> >
> >
> > On Thu, May 30, 2013 at 8:16 PM, Igor Vaynberg <[email protected]
> > >wrote:
> >
> > > On Thu, May 30, 2013 at 12:37 PM, tetsuo <[email protected]>
> > wrote:
> > > > -1000!
> > > >
> > > > This will be horrible! Even with the current API, most generics I
> have
> > to
> > > > declare in my code don't add anything to type safety. For example:
> > >
> > > while i am also not a fan of having component generified i do believe
> > > the example below is a bit contrived.
> > >
> > > first, i hope most people do not use PropertyModels because they are
> > > not compile-time-safe. there are plenty of project that implement
> > > compile-time-safe models, personally i prefer
> > > https://github.com/42Lines/metagen to using proxy-based solutions.
> > >
> > > further, i hope even less people use compound property models. they
> > > are even more unsafe then property models and make your code even more
> > > fragile. i would hate to refactor code that uses CPMs.
> > >
> > > > add(new Form<Person>("form", new CompoundPropertyModel<Person>(new
> > > > PropertyModel<Person>(this, "person")))
> > > > .add(new TextField<String>("name"))
> > > > .add(new TextField<Integer>("age"))
> > > > .add(new TextField<Double>("salary"))
> > > > .add(new Button("save", new
> > PropertyModel<Person>(this,"person")){
> > > > public void onSubmit() {
> > > >
> repository.save((Person)getForm().getDefaultModelObject());
> > > > }
> > > > });
> > > >
> > > > In my experience, this kind of code is fairly common in Wicket
> > > > applications. Every form component must be declared with a type, but
> > none
> > > > has *any* kind of type safety gain.
> > >
> > > but how often do you declare a form component without adding any
> > > validators to it? the generic type of component also makes sure you
> > > add the correct validator. for example it wont let you add a validator
> > > that expects strings to a component that produces integers.
> > >
> > > also, not sure why you are replicating the model in Button. first, the
> > > Button uses its model to fill its label; secondly, in real code the
> > > model would be in a final var or field that things like onsubmit can
> > > access easily.
> > >
> > > -igor
> > >
> > >
> > > >
> > > > - The property model uses reflection, so its type can't be verified
> by
> > > the
> > > > compiler (this.person could be anything, not just a Person).
> > > > - Generics will guarantee that the form model will be of type Person,
> > but
> > > > since it's all declared inline, and the real model isn't verifiable,
> it
> > > > just adds lots of verbosity without any real gain.
> > > > - Most form components use the implicit model, that also uses
> > reflection,
> > > > and also can't verify the actual type of the underlying property, at
> > > > compilation time. Even in runtime, *the type information is lost due
> > > erasure
> > > > *, so it can't use it to do any additional verification.
> > > > *- Worse, you can even declare the "name" TextField as <Integer> or
> > > > <Double> (while maintaining the 'text' attribute as String), and
> since
> > > > there is no type information at runtime, it doesn't matter. It won't
> > even
> > > > throw an exception (it will just work normally).* In this case, the
> > type
> > > > declaration is simply a lie.
> > > >
> > > > Just pain, no gain. In my code, I sometimes just add a
> > @SuppressWarnings(
> > > > "rawtypes") to the class, and remove all useless generic type
> > > declarations.
> > > > If everything will be required to declare them, I will have do it
> more
> > > > frequently.
> > > >
> > > > That said, repeater components benefit greatly from generics. So do
> > > custom
> > > > models, validators, and converters. Or the rare cases that we
> > explicitly
> > > > declare the form component model. But forcing everything to be
> > > > generic-typed will just make Wicket extremely verbose to use, with
> very
> > > > little benefit.
> > > >
> > > >
> > > >
> > > >
> > > > On Thu, May 30, 2013 at 4:00 AM, Martin Grigorov <
> [email protected]
> > > >wrote:
> > > >
> > > >> Hi,
> > > >>
> > > >> I just pushed some initial work for [1] and [2] in
> > > >> branch generified-component-4930.
> > > >>
> > > >> So far it doesn't look nice.
> > > >>
> > > >> The added generics break somehow setMetaData/getMetaData methods -
> you
> > > can
> > > >> see compilation errors in Component and Page classes. I think it is
> > > caused
> > > >> by the anonymous instance of MetaDataKey ( new MetaDataKey<T>(type)
> {}
> > > ).
> > > >>
> > > >> Also the visit*** methods do not compile at the moment, but even if
> we
> > > find
> > > >> a way to fix their signature I think writing a visitor will become
> > quite
> > > >> cumbersome.
> > > >> At the moment we have IVisitor
> > > >> and org.apache.wicket.util.iterator.AbstractHierarchyIterator which
> do
> > > the
> > > >> same job. The Iterator API is supposed to be simpler to write for
> the
> > > >> users. Maybe we can drop IVisitor ... ?!
> > > >>
> > > >> I'd like to ask for help with this task. It is supposed to be the
> > > biggest
> > > >> API break for Wicket 7.0. My current feeling is that the end result
> > > won't
> > > >> be very pleasant for the user-land code.
> > > >> For example the application code will have to do something like:
> > > >>
> > > >> WebMarkupContainer<Void> wmc = new WebMarkupContainer<>("id")
> > > >>
> > > >> It is not that much but we have to decide whether we want it.
> > > >> But first let's try to fix the compilation problems.
> > > >>
> > > >>
> > > >> 1. https://issues.apache.org/jira/browse/WICKET-4930 (Add generics
> to
> > > >> o.a.w.Component)
> > > >> 2.
> > > >>
> > > >>
> > >
> >
> https://cwiki.apache.org/confluence/display/WICKET/Wicket+7.0+Roadmap#Wicket7.0Roadmap-Genericsfororg.apache.wicket.Component
> > > >>
> > >
> >
>