I\'m working with jsf 2
and I\'m getting some behaviour which I find hard to explain or understand.
I have several independent h:form
s.
I don't use MyFaces, so I won't go in its specifics. But for what is worth, on Mojarra the getter is also called for <ui:repeat>
. However, the stack is imo more clear as to what is happening. Here's the Thread#dumpStack()
until FacesServlet#service()
:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1249)
at mypackage.Bean.getList(Bean.java:21)
at sun.reflect.GeneratedMethodAccessor51.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at com.sun.el.parser.AstValue.getValue(AstValue.java:116)
at com.sun.el.parser.AstValue.getValue(AstValue.java:163)
at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at com.sun.faces.facelets.component.UIRepeat.getValue(UIRepeat.java:272)
at com.sun.faces.facelets.component.UIRepeat.getDataModel(UIRepeat.java:248)
at com.sun.faces.facelets.component.UIRepeat.setIndex(UIRepeat.java:442)
at com.sun.faces.facelets.component.UIRepeat.doVisitChildren(UIRepeat.java:661)
at com.sun.faces.facelets.component.UIRepeat.visitTree(UIRepeat.java:619)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:240)
at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188)
at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:452)
at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:148)
at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303)
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:189)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:113)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
// Remnant omitted for brevity.
It is thus happening during the restore view phase when the state management needs to visit the entire component tree. The UIRepeat
in turn needs to set the row index when its children are to be visited.
According to the UIRepeat#doVisitChildren()
source the row index is set to -1
. The final goal is to just visit its children in the tree, not to iterate over the model value nor to render anything. It just needs the DataModel
in order to be able to set the row index. The value of the datamodel is the list for which you're seeing the getter being invoked. If anything is fine, this getter should be invoked only once during restore view phase. However, if it was invoked during for example render response phase as well, then you may be worrying about this because it would have been completely unnecessary.