@PostConstruct method is called even if the ManagedBean has already been instantiated (e.g. on AJAX-calls) [duplicate]
Asked Answered
K

1

10

I have a @ViewScope ManagedBean and a @PostConstruct initialisation method. This method is called when a new instance is created, but also on every ajax call. Why is this so?

On an AJAX-call the init-Method is called and executed, but no changes are visible. For example if I change a property in the init-Method, this is only visible on instatiation and not for AJAX-calls. For AJAX-calls the value change is not persistent in the @ViewScoped Bean.

Can anyone tell why this is so? How can I change this?

Kenzie answered 10/1, 2012 at 13:51 Comment(3)
@PeterGwiazda But not really answered.Ottavia
OK. My comment is the same: Paste your JSF page. It looks like view root is recreated. It happens for example when you try to use JSTL (e.g. c:if) in JSF code.Willettawillette
@PeterGwiazda My code is too big to paste in here. I will try to create a short version. I experience this behavior in all view scoped beans of mine. I also use <ui:include> and Richfaces, if this helps.Kenzie
C
11

This is not normal behavior. This will happen if you bind tag handler attributes or the binding attribute of JSF components to a property of a view scoped bean while partial state saving is turned on. This is known as issue 1492 which is fixed in (the upcoming) Mojarra 2.2.

In general, you can recognize tag handlers by the lack of the rendered attribute. E.g. <c:if>, <f:validator>, <ui:include>, etc. If you bind an attribute of such a tag handler to a property of the view scoped bean like follows

<c:if test="#{viewScopedBean.something}"></c:if>
<h:inputText><f:validator binding="#{viewScopedBean.validate}" /></h:inputText>
<ui:include src="#{viewScopedBean.includePage}" />

then the view scoped bean will be recreated everytime the view is to be restored from a partially saved state. This is a chicken-egg issue with the view scope, because in order to get the right view scoped bean, it has to be extracted from the restored view.

This will also happen if you reference a property of a view scoped bean in the binding attribute of a JSF component.

<h:someComponent binding="#{viewScopedBean.someComponent}" />

See also:

Capel answered 10/1, 2012 at 14:9 Comment(4)
Thanks a lot. This is well the case. I have a <c:set var="someVar" value="#{myBean.someVar}" /> in every view. I will try out some of your solutions.Kenzie
You can use <ui:param> instead to alias a long EL expression.Capel
This problem is indeed a little bit more complex. Setting the partial state saving method to false worked for me. The other solutions are not that easy to use as of not knowing this is so, there a lot of places where I use such bindings. Upgrading to the latest JSF version did not work out of the box. Probably this would be the best solution for the future. Still, many thanks for your answer and explanations! Question answered.Kenzie
My solution is to keep only user inputs and action listeners (they use user inputs) in view-scoped beans. It's often one view bean per page. Everyting else - component bindings, possible options (for combo box, list, etc.) I keep in request-scoped beans. Session-coped bean is used only if necessary. I never use JSTL - it makes no sense in JSF. It's like changing JSF code during compilation. It makes no sense to restore view if you use JSTL. Sticking to those rules made everything work for me without a glitch.Willettawillette

© 2022 - 2024 — McMap. All rights reserved.