Rootless value binding for property in POJO
hispanic Jun 6, 2008 12:09 AMI have an action class that is intended to process a form submission. In its first iteration, it contained private String fields like so:
@In(required = false) private String firstName; @In(required = false) private String middleName;
and the submitting facelet page had references like so:
<s:decorate id="first_name_dec" template="input.xhtml"> <ui:define name="label">First Name</ui:define> <h:inputText id="firstName" value="#{firstName}" /> </s:decorate> <s:decorate id="middle_name_dec" template="input.xhtml"> <ui:define name="label">Middle Name</ui:define> <h:inputText id="middleName" value="#{middleName}" /> </s:decorate>
Then I decided to refactor and placed the Strings into a simple POJO, like so:
public class Query { private String firstName; private String middleName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getMiddleName() { return middleName; } public void setMiddleName(String middleName) { this.middleName = middleName; } }
Then things stopped working like I would assume they should work. I modified my action class to reference the POJO instead of the individual Strings, like so:
@In(create=true, required = false) private Query query;
and I modified the submitting facelet page like so (prepending the value bindings with query.
):
<s:decorate id="first_name_dec" template="input.xhtml"> <ui:define name="label">First Name</ui:define> <h:inputText id="firstName" value="#{query.firstName}" /> </s:decorate> <s:decorate id="middle_name_dec" template="input.xhtml"> <ui:define name="label">Middle Name</ui:define> <h:inputText id="middleName" value="#{query.middleName}" /> </s:decorate>
But this raised the following error:
javax.el.PropertyNotFoundException: /query.xhtml @24,71 value="#{query.firstName}": Target Unreachable, identifier 'query' resolved to null
At first, I thought it was stating that the Query object was null. But now I believe it means that query
doesn't bind to anything. If I were to place the @Name annotation on the Query class or create a @Factory method for query
, it would work. But this is distasteful to me - having to globally namespace a component that may only be used on one page.
More to the point, why does it appear that value bindings with NO separating dot
notation (e.g., {firstName}) implicitly resolve as properties of the target action class, but value bindings WITH a separating dot
notation (e.g., {query.firstName}) completely lose that implicit behavior? To me, that is a failing of the framework.
My workaround is to create a getter and setter for my Query property and modify my value bindings like so (prepending the value bindings with queryAction.
):
<s:decorate id="first_name_dec" template="input.xhtml"> <ui:define name="label">First Name</ui:define> <h:inputText id="firstName" value="#{queryAction.query.firstName}" /> </s:decorate> <s:decorate id="middle_name_dec" template="input.xhtml"> <ui:define name="label">Middle Name</ui:define> <h:inputText id="middleName" value="#{queryAction.query.middleName}" /> </s:decorate>
But I don't like the need for the extra getter and setter and verbose value bindings. Is there a way to directly reference a property WITHIN an unnamed POJO field of an action class (just like a top-level String or primitive) that I don't know about? If not, does anyone agree that this would be a beneficial addition to the framework?
I appreciate any and all feedback. Thanks.
Environment:
- JBoss v4.2.2
- Seam v2.0.2.CR1
- JBoss Portal v2.6.4
- PortletBridge v1.0.0.B2
Mike.....