JSF 2.0 Managed Property object has two different instances, when I to open page and to do ajax request - jsf

all
I novice in JSF2 (used Mojarra + primeFaces on tomcat7) and I get strange behavior of ManagedProperty object:
#ManagedBean
#ViewScoped
public class CreateFactMB implements Serializable{
#ManagedProperty(value="#{collectionFactTable}")
private CollectionFactTable collectionFactTable; //SessionBean
...
//setters/getters
I printed object when I open page (refresh brouser) I see one instance of collectionTree
mbeans.CollectionFactTable#12803ba
But when I do ajax request
<p:commandButton id="btn1" value="Save" update="growl"
actionListener="#{createFactMB.doUpdate}" />
In doUpdate I see another instance of my collectionTree
mbeans.CollectionFactTable#625c49
It's problem because I can not do change while ajax action (because I have just copy)
Anybody can help me? What I'M doing not right?

I think you have a misunderstanding of how SessionScoped persistence works in JSF. This behavior is expected and normal.
At the beginning of the request all of the managed beans are instantiated regardless of scope. In the Restore View phase, the session based persistence values are set to the new managed bean object, effectively restoring the SessionScoped bean back to its last state before the last Response was sent.
Once the Response is complete and has been sent the data in these managed bean instances is persisted and the objects dereferenced for garbage collection. The process begins anew at the next request, regardless if it is Ajax or not.

Related

JSF #ViewScoped - #Postconstruct called multiple times [duplicate]

What does the view scope mean? Can anyone explain about it, so that I can understand how it differs from the request scope?
A #ViewScoped bean lives exactly as long as a JSF view. It usually starts with a fresh new GET request, or with a navigation action, and will then live as long as the enduser submits any POST form in the view to an action method which returns null or void (and thus navigates back to the same view). Once you refresh the page, or return a non-null string (even an empty string!) navigation outcome, then the view scope will end.
A #RequestScoped bean lives exactly as long a HTTP request. It will thus be garbaged by end of every request and recreated on every new request, hereby losing all changed properties.
A #ViewScoped bean is thus particularly more useful in rich Ajax-enabled views which needs to remember the (changed) view state across Ajax requests. A #RequestScoped one would be recreated on every Ajax request and thus fail to remember all changed view state. Note that a #ViewScoped bean does not share any data among different browser tabs/windows in the same session like as a #SessionScoped bean. Every view has its own unique #ViewScoped bean.
See also:
How to choose the right bean scope?
The benefits and pitfalls of #ViewScoped

Does JSF prevent calls to unrendered managed bean actions by tampered requests

A method in a managed bean is protected by JSF? See the code:
Managed Bean
#ManagedBean
public class My {
public void test() {
System.out.println("called");
}
}
XHTML
<h:form>
<h:commandButton rendered="true" action="#{my.test}" value="Teste" />
</h:form>
If the button is not rendered (rendered="false"), a HTTP POST request (as the button would do) can be done and call the test() method?
In other words, JSF prevents calls to managed beans methods by tampered requests?
In other words, JSF prevents calls to managed beans methods by tampered requests?
Yes.
JSF re-evaluates the component's rendered attribute during apply request values phase. If it's false, then in case of UICommand components the ActionEvent simply won't be queued, regardless of whether the (tampered) HTTP request parameter indicates that the button is being pressed.
JSF has similar safeguard against tampered requests on the disabled and readonly attributes, also those of UIInput components. And, in UISelectOne/UISelectMany components, JSF will validate if the submitted value is indeed part of the provided available options.
JSF does this all also with help of the view state. If JSF were stateless, there would be more risk that one or other may fail if those attributes suddenly become request scoped instead of view scoped.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated - point 5
Validation Error: Value is not valid
How to disable/enable JSF input field in JavaScript?
What is the usefulness of statelessness in JSF?

Applying request values to entity bean loaded with id from inputHidden before other fields

I have a facelet template with:
<f:metadata>
<o:viewParam name="id" value="#{homeBean.id}" />
</f:metadata>
<h:form>
<h:inputHidden value="#{homeBean.id}" />
<h:inputText value="#{homeBean.user.firstName}" />
<h:commandButton value="Submit" action="#{homeBean.onSave()}" />
</h:form>
and a request scoped bean with:
#Named
#RequestScoped
public class HomeBean {
private Integer id;
private User user;
public void setId(Integer id) {
System.out.println("setId called");
user = // code for loading User entity bean with supplied id
}
// other accessors for id and user
}
Initial page load works well, entity is loaded and displayed in a form, inputHidden is set to entity id. Problem is that submit throws:
javax.el.PropertyNotFoundException - Target unreachable, base expression '. user' resolved to null
probably because getUser is called before setId. How can I solve this? I really would like to have a request scoped bean, I know that this can be easily solved with at least viewaccess scoped bean.
EDIT: Now i noticed that exception is thrown in Process Validations phase, I initially thought that exception is thrown in Update Model Values phase. I changed "private User" to "private User user = new User()" and now it's OK, but it feels little weird.
Regards,
Pavel
The OmniFaces <o:viewParam> sets the request parameter only in the initial request and not in postbacks. This is intented to be used with #ViewScoped beans so that the request parameter isn't unnecessarily been validated, converted and updated on every single postback (because it's already still present in a view scoped bean). The API documentation and the showcase example also explicitly mentions that it should be used with view scoped beans.
You've there however a request scoped bean which get trashed and recreated on every single request, also on postbacks to the same view. So the user property disappears and falls back to default null on every subsequent postback request.
There are basically 2 ways to fix it:
Replace <o:viewParam> by <f:viewParam>. It will call the setter on every request, also on postbacks.
Replace #Named #RequestScoped by #ManagedBean #ViewScoped, this way the bean will live as long as you're interacting with the same view. Or if you insist in using CDI, use #Named #ConversationScoped instead, but you have to manage the begin and end of the conversation yourself.

JSF 1.2: How to keep request scoped managed bean alive across postbacks on same view?

Is it possible to keep a request scoped bean alive across postbacks on the same page?
The general problem is, as the bean gets trashed on end of request and recreated on every form submit, for example the booleans behind dynamically manipulated disabled, readonly and rendered get reset to their default values and cause the forms to not work as intented anymore.
I'll assume that the session scope is not an option, otherwise this question makes little sense.
You can do it using Tomahawk <t:saveState>. Add the following line somewhere to the page:
<t:saveState value="#{bean}" />
RichFaces <a4j:keepAlive> does also the same:
<a4j:keepAlive beanName="#{bean}" />
Or if there is room, upgrade to at least JSF 2.x and put the bean in view scope:
#ManagedBean
#ViewScoped
public class Bean implements Serializable {
// ...
}
Regardless of the way, the same bean will be there when you postback to the same view and keep returning null or void from action methods.
See also:
How to choose the right bean scope?
Difference between View and Request scope in managed beans
Not really, unless you store the Bean somewhere e.g. a Map in application scope, to retrieve it later.
Why not just make it Session scoped? This is what Session scope is there for, so multiple Requests during the same Session can hit the same state.

Difference between View and Request scope in managed beans

What does the view scope mean? Can anyone explain about it, so that I can understand how it differs from the request scope?
A #ViewScoped bean lives exactly as long as a JSF view. It usually starts with a fresh new GET request, or with a navigation action, and will then live as long as the enduser submits any POST form in the view to an action method which returns null or void (and thus navigates back to the same view). Once you refresh the page, or return a non-null string (even an empty string!) navigation outcome, then the view scope will end.
A #RequestScoped bean lives exactly as long a HTTP request. It will thus be garbaged by end of every request and recreated on every new request, hereby losing all changed properties.
A #ViewScoped bean is thus particularly more useful in rich Ajax-enabled views which needs to remember the (changed) view state across Ajax requests. A #RequestScoped one would be recreated on every Ajax request and thus fail to remember all changed view state. Note that a #ViewScoped bean does not share any data among different browser tabs/windows in the same session like as a #SessionScoped bean. Every view has its own unique #ViewScoped bean.
See also:
How to choose the right bean scope?
The benefits and pitfalls of #ViewScoped

Resources