Skip to main content

Using ui:include with View Scoped beans

9 replies [Last post]
mdergacz
Offline
Joined: 2008-04-01

I am only new to JSF but I have found myself stuck on a problem for quite some time and I am not sure if it is purely down to lack of knowledge to the lifecycle of the view scope.

The scenario is that I want to use a view scoped bean to store the state of a component. There is one property on the bean that I want to read out and that is of the path for the currently displayed page (path to the file such as /blah/foo.xhtml). I use it in the following manner:

There are some buttons on the page that change the viewPage property on MyViewBean which would cause the value of viewPage to change and thus a different component would be rendered. This is because I don't know which page to display at design time.

The behaviour that ensured was that no matter what buttons you clicked (made sure the request was not causing a redirect) the MyViewBean bean was being created every single request. I even created a @PostConstruct annotated method, set a breakpoint there and could confirm a new view scoped variable was being created every request.

If I changed MyViewBean to be SessionScoped, it would behave as expected however I wanted the behaviour to be view based so two browser windows could co-exist in which the view scope fits the bill!

After removing the , using the debugger, I could confirm that the view scoped bean being was being managed correctly and that a new instance was not being created every request as expect.

After some digging around, it looks like my issue starts with the way the order the view scope is set in the restore view phase of JSF. Turns out, the EL expressions are executed before JSF restores the view scope map. The consequence is that when the FaceletViewHandlingStrategy.buildView() is run, only session scoped beans are available and thus JSF creates a new view scoped object and uses that.

Is this the intended behaviour of view scopes or should I be looking at creating my own custom scope?

Thanks in advance,

-- Marc

Message was edited by: mdergacz

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Ryan Lubke

On 2/11/10 2:12 AM, webtier@javadesktop.org wrote:
> I am only new to JSF but I have found myself stuck on a problem for quite some time and I am not sure if it is purely down to lack of knowledge to the lifecycle of the view scope.
>
> The scenario is that I want to use a view scoped bean to store the state of a component. There is one property on the bean that I want to read out and that is of the path for the currently displayed page (path to the file such as /blah/foo.xhtml). I use it in the following manner:
>
> There are some buttons on the page that change the viewPage property on MyViewBean which would cause the value of viewPage to change and thus a different component would be rendered. This is because I don't know which page to display at design time.
>
> The behaviour that ensured was that no matter what buttons you clicked (made sure the request was not causing a redirect) the MyViewBean bean was being created every single request. I even created a @PostConstruct annotated method, set a breakpoint there and could confirm a new view scoped variable was being created every request.
>
> If I changed MyViewBean to be SessionScoped, it would behave as expected however I wanted the behaviour to be view based so two browser windows could co-exist in which the view scope fits the bill!
>
> After removing the, using the debugger, I could confirm that the view scoped bean being was being managed correctly and that a new instance was not being created every request as expect.
>
> After some digging around, it looks like my issue starts with the way the order the view scope is set in the restore view phase of JSF. Turns out, the EL expressions are executed before JSF restores the view scope. The consequence is that when the FaceletViewHandlingStrategy.buildView() is run, only session scoped beans are available and thus JSF creates a new view scoped object and uses that.
>
> Is this the intended behaviour of view scopes or should I be looking at creating my own custom scope?
>
Do you have components within your view using the binding attribute in
concert with view scoped beans?

> Thanks in advance,
>
> -- Marc
> [Message sent by forum member 'mdergacz' (marc@skytix.com.au)]
>
> http://forums.java.net/jive/thread.jspa?messageID=386057
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: webtier-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

mdergacz
Offline
Joined: 2008-04-01

I tried a variety of methods.

I tried using a view scoped bean and trying to obtain a UIComponent off it using something like:

But, as in the original case, the #{MyViewScopedBean.someComponent} expression is evaluated before the view scope is restored (because it is evaluated as part of the restoreView process) so, every page load, a new instance of MyViewScopedBean is created.

I have resigned to the fact that View scopes in JSF 2.0 are somewhat useless for what I am trying to do for as long as the scope is restored after the component tree has been rebuilt. I can see exactly where it is happening in the code in JSF, it seems a little silly as to where it is occurring, however I really don't know what the implications are if it was to change.

Ryan Lubke

On 2/15/10 4:12 PM, webtier@javadesktop.org wrote:
> I tried a variety of methods.
>
> I tried using a view scoped bean and trying to obtain a UIComponent off it using something like:
>
>
>
> But, as in the original case, the #{MyViewScopedBean.someComponent} expression is evaluated before the view scope is restored (because it is evaluated as part of the restoreView process) so, every page load, a new instance of MyViewScopedBean is created.
>
> I have resigned to the fact that View scopes in JSF 2.0 are somewhat useless for what I am trying to do for as long as the scope is restored after the component tree has been rebuilt. I can see exactly where it is happening in the code in JSF, it seems a little silly as to where it is occurring, however I really don't know what the implications are if it was to change.
>

The workaround is to set the javax.faces.PARTIAL_STATE_SAVING context
initialization parameter to false.
Doing so stops the logic that re-creates the view from the template
before applying state deltas.

> [Message sent by forum member 'mdergacz' (marc@skytix.com.au)]
>
> http://forums.java.net/jive/thread.jspa?messageID=386885
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: webtier-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

illia.romanenko
Offline
Joined: 2011-03-18

I can confirm too - that this fixes problem. Thanks!

mdergacz
Offline
Joined: 2008-04-01

Hrmm.. I might give that a shot tonight when I get a chance to work on the project again.

What is the consequence of disabling partial state saving?

Ryan Lubke

On 2/15/10 4:24 PM, webtier@javadesktop.org wrote:
> Hrmm.. I might give that a shot tonight when I get a chance to work on the project again.
>
> What is the consequence of disabling partial state saving?
>
The runtime basically reverts to 1.2-style state saving (which could be
heavy on session
memory if using server side state saving. If using client side state
saving, then the page size increased
by quite a bit) :
- state will be saved and the tree 'serialized' when the view is saved
- when restoring, the 'serialized' tree is reconstructed without
consulting the template
and the state applied.

Partial state saving attempts to reduce the memory consumption or page
size by:
- mark the initial state of the view after the view has been
initialized by a GET.
- when saving the view, the tree structure isn't saved, but any state
changes
made to the component *after* the initial state has been marked
will be saved.
- when a view is restored due to a post-back, the view is
reconstructed by executing
the template (same as the GET case described above) and then the
delta state
is applied afterward.

> [Message sent by forum member 'mdergacz' (marc@skytix.com.au)]
>
> http://forums.java.net/jive/thread.jspa?messageID=386888
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: webtier-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

mdergacz
Offline
Joined: 2008-04-01

Well, that fixes it. Thanks :) I guess RAM is cheap enough to keep adding more. Is this only a temporary solution or will you never be able to use view-scoped beans in this manner?

Ryan Lubke

On 2/16/10 12:11 AM, webtier@javadesktop.org wrote:
> Well, that fixes it. Thanks :) I guess RAM is cheap enough to keep adding more. Is this only a temporary solution or will you never be able to use view-scoped beans in this manner?
>
We'll be looking into how to support this better.
> [Message sent by forum member 'mdergacz' (marc@skytix.com.au)]
>
> http://forums.java.net/jive/thread.jspa?messageID=386932
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: webtier-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: webtier-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: webtier-help@glassfish.dev.java.net

oversteer
Offline
Joined: 2011-03-28

One thing to consider is to disable partial state saving on a per-view basis using this context param:
<context-param>
<param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name>
<param-value>/secure/myPage.xhtml</param-value>
</context-param>
So you keep the benefits of partial state saving unless you need to have 'dynamic ui:include' on a
particular view. I've tested this and it works ok, I think you need Mojarra 2.1 or above, I've only
tested on 2.1.3.
One of these days I'd like to see how much of a benefit partial state saving actually is!