All model classes in Wicket have the ability to be detachable. A detachable model in Wicket is a model which can get rid of a large portion of its state to reduce the amount of memory it takes up and to make it cheaper to serialize when replicating it in a clustered environment. When an object is in the detached state, it contains only some very minimal non-transient state such as an object id that can be used to reconstitute the object from a persistent data store. When a detached object is attached, some logic in the object uses this minimal state to reconstruct the full state of the object. This typically involves restoring fields from persistent storage using a database persistence technology such as JDO or Hibernate.
If you look again at the
IModel, you will notice that this interface extends
IDetachable interface, which has single method
void detach(). The simplest
Model implements this method as a no-op. However, there are other models, which provide true detachable functionality.
To make implementation of detachable models easy,
LoadableDetachableModel provides some basic inheritable logic for attaching and detaching models. The basis for this logic is a transient boolean field which is true when the object is in the attached state and false when it is in the detached state:
Which state a detachable object is in is available via:
This boolean variable is used to determine whether to load the transient object from the persistence technology. Furthermore, it is used in the
detach() method (which implements the
IDetachable interface contract).
The transient object is loaded in the
getObject() method, if necessary.
Put in another words,
LoadableDetachableModel holds a temporary, transient model object, that is set on attaching by calling abstract method
load(), and that will be reset/set to null on detaching.
In the following example, we load objects (persons) on attachement.
During the handling of the request cycle, the list of persons we found by calling
findPersons() is returned when
getObject() is called on the
personListModel. When detached, the model representation is cleaned up.
Another example would be storing a single object which can be reconstituted by its primary key.
Now we have an example of a functioning detachable model that shrinks and then restores its state when replicated in a cluster.
AbstractReadOnlyModel is another simple implementation of
IModel. It has empty logic for detachment and disallows setting an model object, thus becoming read-only model.
StringResourceModel we talked about above is another fine example of loadable detachable (and therefore read-only) model, since resource strings are read-only in nature. Actually, the
StringResourceModel is a subclass of
The first example of property model is
AbstractPropertyModel. It provides implementation details for the
BoundCompoundPropertyModel classes we discussed above by implementing
setObject() using a property expression and conversion type retrieved from a subclass via abstract method
propertyExpression(). The simple
PropertyModel class just returns the property expression and type it was constructed with:
The conversion type is determined in the method
getObjectClass() provided by
Another type of property model,
CompoundPropertyModel, returns the name of the component as its property expression:
BoundCompoundPropertyModel stores a set of bindings internally and returns the property expression for a component based on this information:
Special purpose models
Some components need or use specialized models for their workings. Or, as is the case with components that inherit from
AbstractChoice, they need more than one model. Currently, these specialized models are
FileUpload. You can find information on them in the JavaDocs of the components that use them, or you can take a look at the examples.