Friday, September 16, 2011

Why does f:validateDoubleRange only work for @SessionScoped?

Can someone explain to me why Foo in my example is always null when it gets to the validateDoubleRange class? The end result is the min value for the validator is always 0. The number 3 displays just fine on the page when in the outputText element.
It validates fine if I make the bean `@SessionScoped` instead of `@ViewScoped`

Controller:
import java.io.Serializable;
    import java.math.BigDecimal;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    
    @ViewScoped
    @ManagedBean(name = "fooController")
    public class FooController implements Serializable {
    
        private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FooController.class);
        private static final long serialVersionUID = 1L;
        private Foo foo;
        private BigDecimal amount;
        private Long fooId;
    
        public Long getFooId() {
            return fooId;
        }
    
        public void setFooId(Long fooId) {
            this.fooId = fooId;
            this.foo = new Foo();
            foo.setFooId(fooId);
            foo.setMinAmount(Double.valueOf(3));
            foo.setMaxAmount(Double.valueOf(10));
        }
    
        public Foo getFoo() {
            return foo;
        }
    
        public void sendAmount() {
            log.debug("sendAmount: " + amount);
        }
    
        public BigDecimal getAmount() {
            return amount;
        }
    
        public void setAmount(BigDecimal amount) {
            this.amount = amount;
        }
    
        public static class Foo {
    
            private Long fooId;
            private Double minAmount;
            private Double maxAmount;
    
            public Foo() {
            }
    
            public void setFooId(Long fooId) {
                this.fooId = fooId;
            }
    
            public void setMinAmount(Double minAmount) {
                this.minAmount = minAmount;
            }
    
            public void setMaxAmount(Double maxAmount) {
                this.maxAmount = maxAmount;
            }
    
            public Long getFooId() {
                return fooId;
            }
    
            public Double getMaxAmount() {
                return maxAmount;
            }
    
            public Double getMinAmount() {
                return minAmount;
            }
        }
    }

JSP:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                >
    <f:metadata>
        <f:viewParam name="fooId" value="#{fooController.fooId}" />        
    </f:metadata>
    <h:form id="myForm">
        <h:outputText value="This is correctly displayed: '#{fooController.foo.minAmount}'"/><br/>
        <h:outputText value="My Input:" />
        <h:inputText id="myInput"
                     value="#{fooController.amount}" 
                     required="true"
                     >
            <f:validateDoubleRange minimum="#{fooController.foo.minAmount}" maximum="80"/>
        </h:inputText>
        <h:message for="myInput"/>
        <br/>
        <h:commandButton id="bidButton"
                         value="Place Bid"
                         action="#{fooController.sendAmount}"
                         >
        </h:commandButton>
    </h:form>
</ui:composition>


I am using JSF 2 on JBoss 6.1

------------------------------------------- UPDATE-------------------------------------------
 Thanks to BalusC on StackOverflow I have the answer. "This problem is related to JSF issue 1492." See http://stackoverflow.com/questions/7445417/why-does-fvalidatedoublerange-only-work-for-sessionscoped/7447265#7447265 for the full answer and work arounds.

No comments: