null Long values displayed as 0
Dear all, I just finished to struggle with the display of nullable Long or Integer values. I am using Primefaces 5.0.1 / MyFaces 2.2.4 / OpenWebBeans 1.2.2 / Tomcat 7.0.39. Those values are the result of the evaluation of EL expressions that I create with the following function : public static ValueExpression createValueExpression(String expression, Class clazz) { FacesContext fc = FacesContext.getCurrentInstance(); ELContext elContext = fc.getELContext(); FacesELContext felContext = (FacesELContext)fc.getELContext(); SenatFunctionMapper sfm = SenatFunctionMapper.getInstance(); felContext.setFunctionMapper(sfm); ExpressionFactory expFactory = fc.getApplication().getExpressionFactory(); ValueExpression ret = null; if(clazz==null) { clazz = Object.class; } try { ret = expFactory.createValueExpression(elContext, expression, clazz); } catch (ELException ex) { log.fatal(Erreur de compilation de l'expression EL : ' + expression + ', ex); } return ret; } Until now, I created those value expressions with the real expected class as the third parameter of ExpressionFactory#createValueExpression. The name of this parameter is expectedType, so it seems logical to me to provide the best information I had. So, I provided java.lang.Integer.class or java.lang.Long.class, etc. But when I do that, null values are displayed as 0, either with h:inputText (standard MyFaces control) or p:inputText (PrimeFaces version). The reason being that org.apache.el.ValueExpressionImpl#getValue is implemented the following way @Override public Object getValue(ELContext context) throws PropertyNotFoundException, ELException { EvaluationContext ctx = new EvaluationContext(context, this.fnMapper, this.varMapper); Object value = this.getNode().getValue(ctx); if (this.expectedType != null) { return ELSupport.coerceToType(value, this.expectedType); } return value; } and that ELSupport.coerceToType of a Long or Integer null value is defined as... 0 As those type are numeric, coerceToType calls coerceToNumber, which starts with : public static final Number coerceToNumber(final Object obj, final Class? type) throws ELException { if (obj == null || .equals(obj)) { return coerceToNumber(ZERO, type); } ... } thus, the ZERO value. For the time being, I solved my «problem» by passing a null third parameter to ExpressionFactory#createValueExpression. It works. It has no apparent drawbacks. But I don't get the logic of it. Should'nt ELSupport#coerceToNumber handles this differently ? Thanks in advance for your explanations, Ludovic | | AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT. |
Re: null Long values displayed as 0
Maybe you could try to add property org.apache.el.parser.COERCE_TO_ZERO=false to your JVM Denis/MTL 2014-07-16 13:00 GMT-04:00 l.pe...@senat.fr l.pe...@senat.fr: Dear all, I just finished to struggle with the display of nullable Long or Integer values. I am using Primefaces 5.0.1 / MyFaces 2.2.4 / OpenWebBeans 1.2.2 / Tomcat 7.0.39. Those values are the result of the evaluation of EL expressions that I create with the following function : public static ValueExpression createValueExpression(String expression, Class clazz) { FacesContext fc = FacesContext.getCurrentInstance(); ELContext elContext = fc.getELContext(); FacesELContext felContext = (FacesELContext)fc.getELContext(); SenatFunctionMapper sfm = SenatFunctionMapper.getInstance(); felContext.setFunctionMapper(sfm); ExpressionFactory expFactory = fc.getApplication(). getExpressionFactory(); ValueExpression ret = null; if(clazz==null) { clazz = Object.class; } try { ret = expFactory.createValueExpression(elContext, expression, clazz); } catch (ELException ex) { log.fatal(Erreur de compilation de l'expression EL : ' + expression + ', ex); } return ret; } Until now, I created those value expressions with the real expected class as the third parameter of ExpressionFactory#createValueExpression. The name of this parameter is expectedType, so it seems logical to me to provide the best information I had. So, I provided java.lang.Integer.class or java.lang.Long.class, etc. But when I do that, null values are displayed as 0, either with h:inputText (standard MyFaces control) or p:inputText (PrimeFaces version). The reason being that org.apache.el.ValueExpressionImpl#getValue is implemented the following way @Override public Object getValue(ELContext context) throws PropertyNotFoundException, ELException { EvaluationContext ctx = new EvaluationContext(context, this.fnMapper, this.varMapper); Object value = this.getNode().getValue(ctx); if (this.expectedType != null) { return ELSupport.coerceToType(value, this.expectedType); } return value; } and that ELSupport.coerceToType of a Long or Integer null value is defined as... 0 As those type are numeric, coerceToType calls coerceToNumber, which starts with : public static final Number coerceToNumber(final Object obj, final Class? type) throws ELException { if (obj == null || .equals(obj)) { return coerceToNumber(ZERO, type); } ... } thus, the ZERO value. For the time being, I solved my «problem» by passing a null third parameter to ExpressionFactory#createValueExpression. It works. It has no apparent drawbacks. But I don't get the logic of it. Should'nt ELSupport#coerceToNumber handles this differently ? Thanks in advance for your explanations, Ludovic | | AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT. |
Re: null Long values displayed as 0
On 16/07/2014 19:15, titou10 titou10 wrote: Maybe you could try to add property org.apache.el.parser.COERCE_TO_ZERO=false to your JVM Denis/MTL No, COERCE_TO_ZERO is useful in the opposite way, when submitting the value. BTW, I already use it. Thx anyway. Ludovic | | AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT. |
Re: null Long values displayed as 0
Hi All files from org.apache.el comes from the EL library, so it is out of MyFaces scope. I think you cannot override the EL coercion rules, unless you change the underlying EL library. regards, Leonardo 2014-07-16 12:20 GMT-05:00 l.pe...@senat.fr l.pe...@senat.fr: On 16/07/2014 19:15, titou10 titou10 wrote: Maybe you could try to add property org.apache.el.parser.COERCE_TO_ZERO=false to your JVM Denis/MTL No, COERCE_TO_ZERO is useful in the opposite way, when submitting the value. BTW, I already use it. Thx anyway. Ludovic | | AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT. |