Question

I have following code in jsf page, backed by jsf managed bean

<h:dataTable value="#{poolBean.pools}" var="item">
    <h:column>
        <f:facet name="header">
                <h:outputLabel value="Id"/>  
        </f:facet>
        <h:outputText value="#{item.id}"/>
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:outputLabel value="Start Range"/>
        </f:facet>
        <h:inputText value="#{item.startRange}" required="true"/>               
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:outputText value="End Range"/>
        </f:facet>
        <h:inputText value="#{item.endRange}" required="true"/>                            
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:outputText value="Pool type"/>
        </f:facet>            
        <h:selectOneMenu value="#{item.poolType}" required="true">
            <f:selectItems value="#{poolBean.poolTypesMenu}"/>
        </h:selectOneMenu>
    </h:column>
    <h:column>
        <f:facet name="header"/>
        <h:commandButton id="ModifyPool" actionListener="#{poolBean.updatePool}" image="img/update.gif" title="Modify Pool">
            <f:attribute name="pool" value="#{item}"/>
        </h:commandButton>
    </h:column>
</h:dataTable>

This code fragment is dedicated to editing come collection of items. Each row of the table contains "edit" button that submits changed values of the row to the server. It has the item itself as an attribute. Submit is performed by calling actionListener method in the backing managed bean.

This code runs correctly on Glassfish v 2.1

But when the server was updated to Glassfish v 2.1.1, the attribute stopped to be passed correctly. Instead of passing edited item (when we change the values in table row, we are actually changing the underlying object fields), the source item is submitted to server, i.e. the item that was previously given to the page. All the changes that were made on the page are discarded.

I tried to update jsf version from 1.2_02 to 1.2_14 (we are using jsf RI), but it had no effect.

Perhaps anyone came across the same problem? Any help and suggestions will be appreciated.

Was it helpful?

Solution

Glassfish ships with bundled JSF. Glassfish v2.1.1 ships with Mojarra 1.2_13. You actually don't need to have your own JSF libs in the /WEB-INF/lib. I am not sure how this particular problem is caused, but to start, you need to ensure that you don't have JSF version collisions in the classpath.

That said, the preferred JSF 1.2 way of passing bean properties is using f:setPropertyActionListener.

<h:commandButton id="ModifyPool" actionListener="#{poolBean.updatePool}" image="img/update.gif" title="Modify Pool">
    <f:setPropertyActionListener target="#{poolBean.pool}" value="#{item}"/>
</h:commandButton>

Update: I recall something; this problem suggests that you still have a JSF 1.2 version older than 1.2_05 around in the classpath. Handling of component attributes has changed as per this version in favour of performance enhancements. In a nutshell, if you have a jsf-api.jar of older than 1.2_05 in your classpath, while there's a jsf-impl.jar of 1.2_05 or newer in your classpath, you will experience exactly this problem.

The solution is obvious: cleanup your classpath to get rid of the older JSF version. Paths covered by the webapp's default classpath are under each /WEB-INF/lib, Appserver/lib (which is in case of Glassfish somewhere in Appserver/domains/domainname/*) and the JRE/lib and JRE/lib/ext. Keep in mind that Glassfish's javaee.jar includes JSF libraries as well, so you really need to ensure that you don't have that JAR (or any other appserver-specific JAR file) in your /WEB-INF/lib or somewhere else.

OTHER TIPS

You can add JBoss EL and write:

#{poolBean.updatePool(item)}

You don't need the whole Seam for that, works fine with JSF RI.

Probably it has to do with the way JSF 1.2 implements actionListener. In JSF 1.1 and until recent implementations of JSF 1.2 (Richfaces, Trinidad etc) the order was setPropertyActionListener (or Attribute) -> actionListener -> action. In JSF 1.2 and now implemented in Richfaces and Trinidad (not sure about IceFaces) the order is actionListener -> setPropertyActionListener (or Attribute) -> action. I know it is disturbing and very annoying... Who thought of it? What did they have in mind? Anyway, try using an action instead of an actionListener and see if it works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top