1
votes

i am using jsf 2.1.1 and primefaces 3.0.M4. i have a sample jsf page that used to post country comments. i use f:viewparam tag with converter to view country pages. here are the codes:

country.xhtml:

<f:metadata>
        <f:viewParam name="country" value="#{countryBean2.selectedCountry}" converter="countryConverter" required="true"/>
    </f:metadata>

    <h:head>
        <title>Country</title>
    </h:head>

    <h:body>
        <h:form id="form">
            <h:outputText value="#{countryBean2.selectedCountry.countryName}" />
            <br/><br/>
            <h:outputText value="Comment:" />
            <h:inputText value="#{countryBean2.comment}" />
            <br/>
            <p:commandButton value="Send" action="#{countryBean2.sendComment}" update="@this" />
        </h:form>
    </h:body>

CountryBean2.java:

@Named("countryBean2")
@SessionScoped
public class CountryBean2 implements Serializable {
    private EntityCountry selectedCountry;
    private String comment;

    public EntityCountry getSelectedCountry() { return selectedCountry; }
    public void setSelectedCountry(EntityCountry newValue) { selectedCountry = newValue; }

    public String getComment() { return comment; }
    public void setComment(String newValue) { comment = newValue; }

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");

    public void sendComment() {
        EntityManager em = emf.createEntityManager();
        try {
            FacesMessage msg = null;
            EntityTransaction entr = em.getTransaction();
            boolean committed = false;
            entr.begin();
            try {
                EntityCountryComment c = new EntityCountryComment();
                c.setCountry(selectedCountry);
                c.setComment(comment);
                em.persist(c);
                committed = true;
                msg = new FacesMessage();
                msg.setSeverity(FacesMessage.SEVERITY_INFO);
                msg.setSummary("Comment was sended");
            } finally {
                if (!committed) entr.rollback();
            }
        } finally {
            em.close();
        }
    }
}

CountryConverter.java:

public class CountryConverter implements Converter {
    public static EntityCountry country = new EntityCountry();

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("testPU");


    @Override
    public EntityCountry getAsObject(FacesContext context, UIComponent component, String value) {
        EntityManager em = emf.createEntityManager();
        Query query = em.createQuery("SELECT c FROM EntityCountry c WHERE c.countryName = :countryName")
                .setParameter("countryName", value);
        country = (EntityCountry) query.getSingleResult();
        return country;
    }


    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        EntityCountry c = (EntityCountry) value;
        return c.getCountryName();
    }
}

i want to call "setComment" setter without calling CountryConverter, when i am using commandbutton to post comment. how can i do that ?

1

1 Answers

1
votes

Unfortunately, that's by design of the <f:viewParam> component. It will convert the request parameter and set the property on every HTTP request, also on postbacks. In order to change this behaviour, you would need to extend <f:viewParam> with a custom component which doesn't remember the initial request parameter in its state. It's relatiely simple, instead of delegating the setSubmittedValue() and getSubmittedValue() to StateHelper, you just need to make it an instance variable. This is described in detail in this blog.

@FacesComponent("com.my.UIStatelessViewParameter")
public class UIStatelessViewParameter extends UIViewParameter {

    private String submittedValue;

    @Override
    public void setSubmittedValue(Object submittedValue) {  
        this.submittedValue = (String) submittedValue;
    }

    @Override
    public String getSubmittedValue() { 
        return submittedValue;
    }   
}

OmniFaces has an ready-to-use component for this in flavor of <o:viewParam>. Here is the live example.