Sorting model object properties

3 views
Skip to first unread message

Fernando Boucquez

unread,
Apr 24, 2009, 11:46:24 AM4/24/09
to wicket-w...@googlegroups.com

Hello, i have the following error in this scenario:

The class Dog is non serializable

public class Dog {

    private String name;

    private int age;

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

That is why i create a model:

private static class DetachedDogModel extends LoadableDetachableModel<Dog> {

        private static final long serialVersionUID = 1L;

        public String internalName;

        public int internalAge;

        public DetachedDogModel(final String name, final int age) {
            super();
            internalName = name;
            internalAge = age;
        }

        @Override
        protected Dog load() {
            return new Dog(internalName, internalAge);
        }

    }

My goal is show a table of read only dogs. This table can be sorted by name and age

         ArrayList<IModel<Dog>> dogs = new ArrayList<IModel<Dog>>();
        dogs.add(new DetachedDogModel("Juan", 12));
        dogs.add(new DetachedDogModel("Pedro", 15));
        dogs.add(new DetachedDogModel("Marta", 22));
        BeanMetaData meta = new BeanMetaData(Dog.class, null, this, null, true);
        add(new BeanForm("wicketBean", dogs, meta));

When i trying to sort for the property name i have the followed exception:

org.apache.wicket.WicketRuntimeException: No get method defined for class: class com.idtech.g2s.host.test.wicketbean.WicketBeanTestPanel$DetachedDogModel expression: name

at org.apache.wicket.util.lang.PropertyResolver.getGetAndSetter(PropertyResolver.java:439)
at org.apache.wicket.util.lang.PropertyResolver.getObjectAndGetSetter(PropertyResolver.java:281)
at org.apache.wicket.util.lang.PropertyResolver.getValue(PropertyResolver.java:90)

at com.googlecode.wicketwebbeans.model.ElementMetaData$$M$bf12fe40.getPropertyValue(ElementMetaData.java:403)
at com.googlecode.wicketwebbeans.model.ElementMetaData$$A$bf12fe40.getPropertyValue(<generated>)

at com.googlecode.wicketwebbeans.model.ElementMetaData.getPropertyValue(ElementMetaData.java:407)
at com.googlecode.wicketwebbeans.containers.BeanTablePanel$PropertyComparator.compare(BeanTablePanel.java:298)


  
Looks like the method getPropertyValue in the class ElementMetaData tries to get the property from the Model (DetachedDogModel ) and not from its value.

to fix that i modified the ElementMetaData method form:

 public Object getPropertyValue(Object bean)
    {      
        if (bean == null) {
            return null;
        }
       
        return PropertyResolver.getValue(
getPropertyName(), bean);
    }

to

 public Object getPropertyValue(Object bean)
    {
        if (bean != null && bean instanceof IModel) {
            bean = ((IModel<?>)bean).getObject();
        }
       
        if (bean == null) {
            return null;
        }
       
        return PropertyResolver.getValue(getPropertyName(), bean);
    }

I have my doubs it this workaround had not secondary effects. Any ideas?

Regards

Fernando

Dan Syrstad

unread,
Apr 26, 2009, 12:04:43 PM4/26/09
to wicket-w...@googlegroups.com
Hi Fernando,

Don't create a DogModel. Dog is still not serializable and I believe that there is an implied contract with Model that the object it contains is serializable. In any case, the "name" property does not exist on DogModel, it exists on Dog.

How about either making Dog just implement Serializable directly or, if that's not possible, subclass Dog and make the subclass Serializable?

WWB is expecting a collection of regular Java beans (POJOs) - not IModels. The collection itself may be wrapped in a model (see BeanTablePanel).

-Dan

Fernando Boucquez

unread,
Apr 27, 2009, 9:14:33 AM4/27/09
to wicket-w...@googlegroups.com
Hi Dan,

On Sun, Apr 26, 2009 at 1:04 PM, Dan Syrstad <dsyr...@gmail.com> wrote:
Hi Fernando,

Don't create a DogModel. Dog is still not serializable and I believe that there is an implied contract with Model that the object it contains is serializable. In any case, the "name" property does not exist on DogModel, it exists on Dog.

Mmm, the objects that the model contains are serializable (the name and the age), maybe the model object can be only a identifier, and the load method, retrieves the fully object from a service or a dao. The example wasn't fully explanatory. 

How about either making Dog just implement Serializable directly or, if that's not possible, subclass Dog and make the subclass Serializable?
 
The object to show is to comlpex to make it serializable, is the main idea of create a custom model. A subclass of the Dog it is too. 
 
WWB is expecting a collection of regular Java beans (POJOs) - not IModels.

Yes, in my domain model the objects that i tyring to show are not serializable, and are not regular POJO. I do not apply this constraint.
 
The collection itself may be wrapped in a model (see BeanTablePanel).

Yes, i have another example:

  Model<List<Dog>> model = new DetachedListDogModel();

  BeanMetaData meta = new BeanMetaData(Dog.class, null, this, null, true);
  add(new BeanForm("wicketBean", model, meta));

Caused by: java.lang.ClassCastException: com.idtech.g2s.host.test.wicketbean.Dog   at com.googlecode.wicketwebbeans.containers.BeanTablePanel$BeanSortableDataProvider.model(BeanTablePanel.java:217)   at org.apache.wicket.markup.repeater.data.DataViewBase$ModelIterator.next(DataViewBase.java:133)
    at org.apache.wicket.markup.repeater.data.DataViewBase$ModelIterator.next(DataViewBase.java:87)
    at org.apache.wicket.markup.repeater.AbstractPageableView$CappedIteratorAdapter.next(AbstractPageableView.java:415)

In this case, the BeanSortableDataProvider tries to create a Model of a non serializable dog:

public IModel model(Object object)
        {
            return new Model((Serializable)object);
        }

and the cast is not valid in this example. This is why i change this example for the original one, a ArrayList<IModel<Dog>>. If you want, i have the full example to show you.

I'm sorry for being so annoying, i really believe in the project, and its fit very good in my application.

Regards,
Fernando


 




Daniel Toffetti

unread,
Apr 27, 2009, 1:52:17 PM4/27/09
to Wicket Web Beans
Hi Fernando,

I know it's perhaps inefficient and boring to add another layer,
but have you considered to write some kind of layer upon your complex
models, which provides you with POJO beans representing the same
data ?? Some structural pattern (Facade and/or Proxy come to mind)
could help.

Hth,

Daniel

On 27 abr, 10:14, Fernando Boucquez <fboucq...@gmail.com> wrote:

> >> Fernando

Dan Syrstad

unread,
Apr 27, 2009, 7:49:45 PM4/27/09
to wicket-w...@googlegroups.com
Hi Fernando,

I don't think you'd want to separately load each object of a collection (e.g., a separate SQL SELECT for each object). It makes more sense to load the whole collection at once via a Model - and WWB supports that. BeanSortableDataProvider does support an IModel for the representation of the collection. So if you load all of your Dogs via your model provided to BeanSortableDataProvider, they need not be Serializable. Furthermore, you can always create your own ISortableDataProvider (see the wicket-databinder code for an example) and provide it to BeanTablePanel.

" ... Yes, in my domain model the objects that i tyring to show are not serializable, and are not regular POJO. I do not apply this constraint."

As far as I can see, Dog is, in fact, a POJO. I think you may be mixing metaphors. Whereas Wicket likes lots of Models wrapping objects, you don't need to wrap every object in a Model with WWB. 

-Dan

Fernando Boucquez

unread,
Apr 28, 2009, 9:34:14 AM4/28/09
to wicket-w...@googlegroups.com
Hi Dan,

On Mon, Apr 27, 2009 at 8:49 PM, Dan Syrstad <dsyr...@gmail.com> wrote:
Hi Fernando,

I don't think you'd want to separately load each object of a collection (e.g., a separate SQL SELECT for each object). It makes more sense to load the whole collection at once via a Model - and WWB supports that.
BeanSortableDataProvider does support an IModel for the representation of the collection. So if you load all of your Dogs via your model provided to

Yes, you are right. Load and create a model for every no serializable object of a list is very inefficient. The objective of the first example is to show the code in the getPropertyValue method on the class ElementMetaData:


public Object getPropertyValue(Object bean)
    {      
        if (bean == null) {
            return null;
        }
       
        return PropertyResolver.getValue( getPropertyName(), bean);
    }
and a posible change for:


 public Object getPropertyValue(Object bean)
    {
        if (bean != null && bean instanceof IModel) {
            bean = ((IModel<?>)bean).getObject();
        }
       
        if (bean == null) {
            return null;
        }
       
        return PropertyResolver.getValue(getPropertyName(), bean);
    }

Nothing more.

if i create a model of this type: IModel<List<Dog>>

The BeanSortableDataProvider class throws a ClassCastException on this method:

public IModel model(Object /*A dog*/ object)
        {
            return new Model((Serializable)object);
      }
 
BeanSortableDataProvider, they need not be Serializable. Furthermore, you can always create your own ISortableDataProvider (see the wicket-databinder code for an example) and provide it to BeanTablePanel.

I will check create a custom ISorteableDataProvider for the BeanTablePanel. Thanks. Maybe a sub class of BeanSortableDataProvider where the method:

public IModel model(Object /*A dog*/ object)

returns a custom model of a dog.


" ... Yes, in my domain model the objects that i tyring to show are not serializable, and are not regular POJO. I do not apply this constraint."

As far as I can see, Dog is, in fact, a POJO. I think you may be mixing metaphors. Whereas Wicket likes lots of Models wrapping objects, you don't need to wrap every object in a Model with WWB. 

Yes, in my real domain model the object ( not a Dog ) that i try to show is not a simple POJO.

Regards,
Fernando

 
Reply all
Reply to author
Forward
0 new messages