tags:

views:

434

answers:

1

I have a custom EntityHome class. I wire the dependent entity in the wire method, but when I call the action (persist) the wired component is always null.

What could be the reason, similar code generated by seam gen is apparently working.

Here is the entity class.

The round.teeSet component is always null when persist is called, although it is shown in the jsf page.

Note: Seam version: 2.2.0.GA Jboss: jboss-5.1.0.GA

I have overrden persist method to log the value of the wired element.

@Name("roundHome")
@Scope(ScopeType.CONVERSATION)
public class RoundHome extends EntityHome<Round>{

    @In(required = false)
    private Golfer currentGolfer;

    @In(create = true)
    private TeeSetHome teeSetHome;

    @Override
    public String persist() {
        logger.info("Persist called");
        if (null != getInstance().getTeeSet() ) {
            logger.info("teeSet not null in persist");
        } else {
            logger.info("teeSet null in persist");
            // wire();
        }
        String retVal =  super.persist();    //To change body of overridden methods use File | Settings | File Templates.
        return retVal;
    }

    @Logger
    private Log logger;

    public void wire() {

        logger.info("wire called");
        TeeSet teeSet = teeSetHome.getDefinedInstance();


        if (null != teeSet) {
            getInstance().setTeeSet(teeSet);
            logger.info("Successfully wired the teeSet instance with color: " + teeSet.getColor());
        }
    }

    public boolean isWired() {
        logger.info("is wired called");
        if(null == getInstance().getTeeSet()) {
            logger.info("wired teeSet instance is null, the button will be disabled !");
            return false;
        }
        else {
            logger.info("wired teeSet instance is NOT null, the button will be enabled !");
            logger.info("teeSet color: "+getInstance().getTeeSet().getColor());
            return true;
        }
    }

    @RequestParameter
    public void setRoundId(Long id) {
        super.setId(id);
    }

    @Override
    protected Round createInstance() {
        Round round = super.createInstance();
        round.setGolfer(currentGolfer);
        round.setDate(new java.sql.Date(System.currentTimeMillis()));
        return round;
    }
}

Here the xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;


<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:s="http://jboss.com/products/seam/taglib"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:a="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"
    template="layout/template.xhtml">

<ui:define name="body">
    <h:form id="roundform">
        <rich:panel>
            <f:facet name="header>">
                #{roundHome.managed ? 'Edit' : 'Add' } Round
            </f:facet>
            <s:decorate id="dateField" template="layout/edit.xhtml">
                <ui:define name="label">Date:</ui:define>
                <rich:calendar id="date" datePattern="dd/MM/yyyy" value="#{round.date}"/>
            </s:decorate>


            <s:decorate id="notesField" template="layout/edit.xhtml">
                <ui:define name="label">Notes:</ui:define>
                <h:inputTextarea id="notes" cols="80" rows="3" value="#{round.notes}" />
            </s:decorate>


            <s:decorate id="totalScoreField" template="layout/edit.xhtml">
                <ui:define name="label">Total Score:</ui:define>
                <h:inputText id="totalScore" value="#{round.totalScore}" />
            </s:decorate>


            <s:decorate id="weatherField" template="layout/edit.xhtml">
                <ui:define name="label">Weather:</ui:define>
                <h:selectOneMenu id="weather" value="#{round.weather}">
                    <s:selectItems var="_weather" value="#{weatherCategories}" label="#{_weather.label}"
                                   noSelectionLabel=" Select " />
                    <s:convertEnum/>
                </h:selectOneMenu>
            </s:decorate>


            <div style="clear: both;">
                <span class="required">*</span> required fields
            </div>
        </rich:panel>

        <div class="actionButtons">
            <h:commandButton id="save" value="Save"
                             action="#{roundHome.persist}"
                             rendered="#{!roundHome.managed}" />
            <!-- disabled="#{!roundHome.wired}"  /> -->

            <h:commandButton id="update" value="Update" action="#{roundHome.update}"
                             rendered="#{roundHome.managed}" />

            <h:commandButton id="delete" value="Delete" action="#{roundHome.remove}"
                             rendered="#{roundHome.managed}" />

            <s:button id="discard" value="Discard changes" propagation="end"
                      view="/Round.xhtml" rendered="#{roundHome.managed}" />

            <s:button id="cancel" value="Cancel" propagation="end"
                      view="/#{empty roundFrom ? 'RoundList' : roundFrom}.xhtml"
                      rendered="#{!roundHome.managed}" />

        </div>

        <rich:tabPanel>
            <rich:tab label="Tee Set">
                <div class="association">
                    <h:outputText value="Tee set not selected" rendered="#{round.teeSet == null}" />
                    <rich:dataTable var="_teeSet" value="#{round.teeSet}" rendered="#{round.teeSet != null}">
                        <h:column>
                            <f:facet name="header">Course</f:facet>#{_teeSet.course.name}
                        </h:column>
                        <h:column>
                            <f:facet name="header">Color</f:facet>#{_teeSet.color}
                        </h:column>
                        <h:column>
                            <f:facet name="header">Position</f:facet>#{_teeSet.pos}
                        </h:column>
                    </rich:dataTable>
                </div>
            </rich:tab>
        </rich:tabPanel>
    </h:form>
</ui:define>
</ui:composition>
+1  A: 

I suppose You have a single ScopeType.CONVERSATION (RoundHome) instance without any long-running conversation enabled. So you may have a Temporary conversation which survive until The render response phase.

When you submit your form, because you have a Temporary conversation, You just populate what you submit. It explains why your TeeSet is null. (Your submitted form does not contain any reference to a Tee instance)

If you really want your TeeSet survive until The next submit, you must enable a long-running conversation before showing and disable after submitting your form.

Just an advice: Each Home instance is by default ScopeType.CONVERSATION - inherited from Home. So you can set up your RoundHome as follows

@Name("roundHome")
public class RoundHome extends EntityHome<Round> {

    ...

}
Arthur Ronald F D Garcia
Thanks, looks like you hit the head of the nail. But how can I found out there is some temporary conversation. More over, the other examples of the book which work, don't show any code for starting a long-running conversation.
rangalo
I found it, it is started in the page descriptor, thanks.
rangalo