Question

I want to achieve two goals:

  1. I want my model to be loaded every time from the DB when it's in a life-cycle (for every request there will be just one request to the DB)

  2. I want my model to be attached dynamically to the page and that wicket will do all this oreable binding for me

In order to achieve these two goals I came to a conclusion that I need to use both CompoundPropertyModel and LoadableDetachableModel.

  1. Does anyone know if this is a good approach?

  2. Should I do new CompoundPropertyModel(myLoadableDetachableModel)?

Was it helpful?

Solution

Yes, you are right, it is possible to use

new CompoundPropertyModel<T>(new LoadableDetachableModel<T> { ... })

or use static creation (it does the same):

CompoundPropertyModel.of(new LoadableDetachableModel<T> { ... })

that has both features of compound model and lazy detachable model. Also detaching works correctly, when it CompoudPropertyModel is detached it also proxies detaching to inner model that is used as the model object in this case.

I use it in many cases and it works fine.

EXPLANATION: See how looks CompoundPropertyModel class (I'm speaking about Wicket 1.6 right now):

public class CompoundPropertyModel<T> extends ChainingModel<T>

This mean, CompoundPropertyModel adds the property expression behavior to the ChainingModel.

ChainingModel has the following field 'target' and the constructor to set it.

private Object target;

public ChainingModel(final Object modelObject)
{
...
target = modelObject;
}

This take the 'target' reference to tho object or model.

When you call getObject() it checks the target and proxies the functionality if the target is a subclass of IModel:

public T getObject()
{
    if (target instanceof IModel)
    {
        return ((IModel<T>)target).getObject();
    }
    return (T)target;
}

The similar functionality is implemented for setObject(T), that also sets the target or proxies it if the target is a subclass of IModel

public void setObject(T object)
{
    if (target instanceof IModel)
    {
        ((IModel<T>)target).setObject(object);
    }
    else
    {
        target = object;
    }
}

The same way is used to detach object, however it check if the target (model object) is detachable, in other words if the target is a subclass if IDetachable, that any of IModel really is.

public void detach()
{
    // Detach nested object if it's a detachable
    if (target instanceof IDetachable)
    {
        ((IDetachable)target).detach();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top