Search code examples
jsfinputelplaceholderconditional-operator

javax.el.PropertyNotWritableException when using EL conditional operator in value of UIInput


I get this error message:

javax.el.PropertyNotWritableException: /u/editProfile.xhtml @64,140 value="#{empty userProfile.cfg.gpu or userProfile.cfg.gpu == '' ? usernavmsg.EditMe: userProfile.cfg.gpu}": null

The problem is that when the value of a bean property is null the value of an inputText field switches from my ManagedBean property, to a resource string. So I cannot persist that value.

I request the profile of the user from my database in my managed bean. If a property of the said profile is null, the inplace text holder value is "Edit Me". If it's not null it's the value of that property. Which is working ! However when I submit the form and try to persist a new value or no value at all the error appears. The error only appears for the field that are null to begin with (when I requested them from the db). So the problem is that when the value is null it switch from my ManagedBean property, to a resource string.

I just have a form with this:

<h:outputLabel value="#{usernavmsg.GPU}: "/>
        <p:inplace styleClass="lessDark">
            <p:inputText value="#{empty userProfile.cfg.gpu ? usernavmsg.EditMe: userProfile.cfg.gpu}" />
        </p:inplace>

when I submit the form I want to persist userProfile.cfg in the database which doesn't happen.

Can I work around this ? Is it even possible ?


Solution

  • Conditional statements in EL are indeed not writable. They are read-only. End of story. The same applies to method references in EL as in #{bean.property()}. It must really be a true value expression as in #{bean.property}.

    Your approach of using a (HTML5) "placeholder" is actually wrong. For that you should be using the placeholder attribute, not the value attribute. In older versions of PrimeFaces that do not have a placeholder attribute you'll need passthrough.

    <html ... xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
    ...
    <p:inputText value="#{userProfile.cfg.gpu}" a:placeholder="#{usernavmsg.EditMe}" ... />
    

    Nowadays PrimeFaces offers a placeholder attribute.

    <p:inputText value="#{userProfile.cfg.gpu}" placeholder="#{usernavmsg.EditMe}" ... />