No saved view state - jsf

I have a view scoped bean that has a method call generateLicenseFile.
The method returns a String with this value
/licenseGenerated.xhtml?faces-redirect=true"
The JSF code for the page (agreementDetail.xhtml) looks like this
<h:commandButton value="Generate License File" action="#{agreement.generateLicenseFile}" />
When I click the button, I get an error
javax.servlet.ServletException: /agreementDetail.xhtmlNo saved view state could be found for the view identifier: /agreementDetail.xhtml
Any ideas?
--EDIT--
Just FYI, the "generateLicenseFile" method is not even executed, since I have logging that proves this.

No Saved View generally occurs when something goes wrong in the JSF Servlet life cycle.Maybe it's because of the View Scoped Bean.Try to change it to Session Scoped and make sure your managed bean entry is there in the faces-config.xml.
Another suggestion is in the generateLicenseFile method in the agreement bean return a String as "someStringName" and make sure you create a navigation handler in Faces Config with navigation rule and navigation case.

Related

How to restore ViewScoped bean when user clicks back button?

Lets say I have a #ViewScoped Bean behind my current page A. Now the user navigates to page B via a normal get request, lets say to www.google.com.
When the user clicks the back button of the browser, I would like to restore the #ViewScope of the previous page, so that it appears exactly as it was left. Is that possible to achieve somehow?
I dont want to make my page A #SessionScoped so that the backing beans do not disturb each others state when opened in two browser tabs.
Since version 2.6 OmniFaces has this feature, is called #ViewScoped(saveInViewState = true) But with some caution!
It's very important that you understand that this setting has potentially a major impact in the size of the JSF view state, certainly when the view scoped bean instance holds "too much" data, such as a collection of entities for a data table, and that such beans will in fact never expire as they are stored entirely in the javax.faces.ViewState hidden input field in the HTML page. Moreover, the #PreDestroy annotated method on such bean will explicitly never be invoked, even not on an unload as it's quite possible to save or cache the page source and re-execute it at a (much) later moment.
A more programmatical solution is the #ConversationScoped. With the convertsation id as parameter can you restore the view.
conversationscope example
Yes it is possible, pass parameter like this using f:param this will pass your parameter to the next screen.
<h:commandLink action="screenName" value="#{search.participantName}">
<f:param value="#{searchcus.participantId}" name="PARTICIPANT_ID"/>
<f:param name="PARENT_SCREEN_CODE" value="SEARCH_PARTICIPANT"/>
</h:commandLink>
After that in init() method get value as a parameter to fetch the result.

Should JSF process non rendered components on Ajax re-rendering?

My page has Ajax show/hide functionality.
During the initial page load my bean methods that are inside a non rendered <f:subview> or <h:panelGroup> are not called. When re-render the #form using Ajax, my bean methods are getting called although the relevant subviews are not rendered. Is this what should happen? (I am using JSF 2.2)
This is the expected behaviour as per my comment above. Unfortunately it comes with some ugly behaviour.
If you an object that is doing anything when using the list, it will work fine on your first request. Even if you have taken your precautions say by loading something with f:event this will not save you on the following AJAX request.
Example:
If you use JPA with each bean managed for the scope of the request and that bean has a lazy collection that is not rendered this will cause the following:
Request 1: Non-rendered components will not be touched i.e. Lazy collections will not initialize
Request 2(Ajax): JSF will try to restore the full view calling your non-loaded lazy collection resulting to an exception.

View-scoped bean recreated on POST when URL parameters not used

I have a view-scoped JSF-managed bean that's backing an xhtml view where I read one parameter from the URL using f:viewParam.
The view presents a form to the user. However, when the user submits the form by pressing the p:commandButton it seems that the view-scoped bean is recreated (I added a #PostConstruct annotation to verify this) and so doesn't remember the instance variable read from the f:viewParam (invId in the code below).
I originally navigate to the view with a GET that includes a URL parameter but the POST message that's send when the user presses the p:commandButton doesn't include the URL parameter. So I am thinking that when the JSF runtime doesn't see the URL parameter on the POST it considers this to be a different view and is recreating the JSF-managed bean. When I change the view scope to session-scoped the code works.
Here's the code:
view
<f:metadata>
<f:viewParam name="invId" value="#{registerBean.invId}"/>
</f:metadata>
<h:form id="registrationForm">
....
<p:commandButton value="register" action="#{registerBean.register}"
icon="ui-icon ui-icon-newwin" ajax="false"/>
</h:form>
backing bean
#ManagedBean
#ViewScoped
public class RegisterBean implements Serializable {
#ManagedProperty(value="#{invId}")
private String invId;
...
update
It turns out that this wasn't related to the URL parameters at all. Following BalusC advice below I removed the c:when tags my view was using (relying on rendered attributes instead for the same effect), and now the view-scoped bean is no longer recreated and the invId field is properly retained.
The problem is not visible in the code posted so far, but it's for JSF 2.0/2.1 a known issue that a view scoped bean will be recreated when one of its properties is been bound to an attribute of a taghandler like JSTL <c:if> or Facelets <ui:include> or a view build time attribute of JSF component, such as id and binding, while partial state saving is enabled (as by default).
The background explanation is that any EL expressions in those attributes are executed during building and restoring the view. As view scoped beans are stored in the view and thus only available after restoring the view, such an EL expression evaluation would cause a brand new and separate view scoped bean to be created. This is basically a chicken-egg issue. It's fixed in the upcoming JSF 2.2.
There are basically 3 solutions:
Change the view accordingly so that those EL expressions are only evaluated during view render time. E.g. replace <c:if>/<c:choose> by rendered.
Or bind those attributes to a request scoped bean (design notice: you can just inject a view scoped bean as a managed property of a request scoped bean).
Turn off partial state saving, if necessary only for the particular view.
See also:
JSTL in JSF2 Facelets... makes sense?
#ViewScoped fails in taghandlers

Backing Bean Initialization

I have a variable in backing bean that needs to get reset to null whenever the associated page is opened using the relevant menu link. Is there a way to run a initialization code in the backing bean whenever the relevant menu link is clicked? Contsructor runs only the first time the menu link is clicked. I guess the bean is then retained in the jsf context and is not getting recreated. Is there a way to ensure a new object of that backing bean is created each time the menu link is clicked? Thanks!
Couldn't you just put the bean in request scope?
Another option would be to use a setpropertyactionlistener on the menu. When the menu is clicked, set the value to "null".
You have the following options:
1 . Change the bean to the request-scoped bean
2 . Use the action attribute to call the method on the backing bean to run the initialization code whenever the link is clicked , something like this:
<h:commandLink action="#{myBean.init}" value="My Link" />
And myBean.init() contains the initialization code

JSF and richfaces: h:commandlink in richfaces table not working properly

When using h:commandlink(or commandbutton) inside a rich:dataTable, the action specified is never invoked, neither is the corresponding managed bean instantiated(whether it is at request or session scope)...
instead, the same request is performed.. (page reloads)..
have seen what appeared to be similar issue on forums, but is not actually the problem i am having..
the h:commandlink /button work ok outside of the rich:datatable..
Does anyone have any advice?
here is a code snippet:
<h:commandLink id="commLink" actionListener="#{hBean.test}" action="#{hBean.viewTranslation}">
<h:outputText value="#{trans.translationName}"/>
</h:commandLink>
</rich:column>
The bean is apparently request scoped and the datamodel is not been loaded during bean's construction (at least, during apply request values phase of the subsequent request). You need to preserve the same datamodel for the subsequent request, else JSF cannot locate the row item associated with the clicked link. The most straightforward way is to load the datamodel in the bean's constructor or #PostConstruct method.
A quick fix/test is to put bean in session scope. The datamodel will then be saved in the session scope and be available in the subsequent request. But this has more impact on user experience (e.g. unexpected results when having the same page opened in different browser windows/tabs in the same session). If you're already on JSF 2.0 (which is likely not the case since you're using RichFaces), then the new view scope would have been the solution.
Related questions:
h:commandLink is not been invoked - contains an overview of all possible causes of this behaviour.
If you are using RichFaces 3.0.0 through 3.3.3, use the tag a4j:keepAlive. It will works even with request scope.

Resources