...
If your ValueEncoder implements ValueEncoderFactory (as ColorEncoder does, above), you can associate your custom ValueEncoder with your entity class so that Tapestry will automatically use it every time a ValueEncoder is needed for items of that type (including for such as with the Select component, RadioGroup, Grid, Hidden and AjaxFormLoop components). Just add lines like the following to your module class (usually AppModule.java):
...
If your Select's "value" parameter is bound to a complex object (not a simple String, Integer, etc.) and you don't provide a ValueEncoder with the "encoder" parameter (and one isn't provided automatically by, for example, the Tapestry Hibernate integration), you'll receive a "Could not find a coercion" exception (when you submit the form) as Tapestry tries to convert the selected option's encoded value back to the object in your Select's "value" parameter. To fix this, you'll either have to 1) provide a ValueEncoder, or 22) provide a Coercion, or 3) use a simple value (String, Integer, etc.) for your Select's "value" parameter, and then you'll have to add logic in the corresponding onSuccess event listener method:
...
But then again, you may as well create a ValueEncoder instead.
Why is this so
...
hard?
Why is Tapestry designed to use SelectModels and ValueEncoders anyway? Well, in short, this design allows you to avoid storing (via @Persist, @SessionAttribute or @SessionState) the entire (potentially large) list of objects in the session or rebuilding the whole list of objects again (though only one is needed) when the form is submitted. The chief benefit is benefits are reduced memory use and more scalable clustering due to having less HTTP session data to replicate across the nodes of a cluster.