This week's book giveaway is in the Servlets forum.
We're giving away four copies of Murach's Java Servlets and JSP and have Joel Murach on-line!
See this thread for details.
The moose likes JSF and the fly likes my a4j:commandButton is failing suddenly, bean is no longer initialized, returning null value. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "my a4j:commandButton is failing suddenly, bean is no longer initialized, returning null value." Watch "my a4j:commandButton is failing suddenly, bean is no longer initialized, returning null value." New topic
Author

my a4j:commandButton is failing suddenly, bean is no longer initialized, returning null value.

ernest cronin
Greenhorn

Joined: Aug 23, 2012
Posts: 8
Hi,
This is my first posting, so please forgive me if I err in formatting. i'm in a bind at work. My application had been working and now i'm getting an error.

I have a web page to update employees. specifically, use an ajax drop down menu and select a new employee initials for the two properties, which are project types. On the page I can select the new employee. But when I hit update, the new employee is not being stored.
Here is the error: HTTP Status 500 - #{employeeStateUtil.setNewEmp()}: java.lang.NullPointerException

Here is the update function in the jsf code:

<!-- Update function -->
<a4j:commandButton value = "update"
rendered = "#{rwwemployees.editable}"
action = "#{employeeStateUtil.setNewEmp()}" //model bean
reRender = "employeestateutiltable" //when the update button is clicked, render the new table
>
</a4j:commandButton>



THIS IS THE VIEWBEAN
Action employeeStateUtil.setNewEmp() is here:

public void setNewEmp() throws SQLException{
System.out.println("in EmplStateUtil setNewEmp");
EmployeeManager empmgr = (EmployeeManager)
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("employeeManager");

//THIS IS NULL!!!
//OTHER PROPERTIES OF THIS BEAN ARE NOT NULL
String newempinit = empmgr.getSelectedInitials();

}

THIS IS THE CONTROLLER BEAN
EmployeeManager is here:

public class EmployeeManager
{
private List<Employee> employees = new ArrayList<Employee>();
//private EmployeeDAO employeedao = new EmployeeDAO();

private String selectedInitials;
.....


public String getSelectedInitials() {

return selectedInitials;
}

//BEAN ISN"T GETTING SET!
public void setSelectedInitials(String selectedInitials) {

this.selectedInitials = selectedInitials;

}

}
Brendan Healey
Ranch Hand

Joined: May 12, 2009
Posts: 218

Please can you edit your post and format the code using the Code button on the toolbar, it's murder trying to make sense
of it at present.

You're using Richfaces 3 I assume from the use of reRender and presumably JSF 1.2. Does the expression language allow
parameters to be passed to action methods in this version? I really can't remember when this was introduced.

action = "#{employeeStateUtil.setNewEmp()}" //model bean

this any better?

action = "#{employeeStateUtil.setNewEmp}" //model bean

Your code excerpts omit the bean scope annotations which could be significant.

Regards,
Brendan.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15951
    
  19

This kind of problem is almost invariably due to having too short a scope on beans. Request Scope is almost completely useless in JSF. Except in very special cases, you should use View or Session Scope.

Another alarm went off when I saw code accessing the FacesContext. You're trying to locate something instead of letting JSF inject it for you. JSF is based on Inversion of Control. IoC means that JSF does a lot of work for you that you would otherwise have to do yourself, and it does it in a way that doesn't tie your code unnecessarily to the environment.


Customer surveys are for companies who didn't pay proper attention to begin with.
ernest cronin
Greenhorn

Joined: Aug 23, 2012
Posts: 8
Tim, you write: You're trying to locate something instead of letting JSF inject it for you. I'm not clear on what you mean. Can you recommend a site where I can gain some more information about this particular scenario?

The scope of my bean variables is session.
Also, I already tried changing to this: action = "#{employeeStateUtil.setNewEmp}" //Throws NullPointerException

<managed-bean-name>employeeManager</managed-bean-name>
<managed-bean-class>controllerbean.EmployeeManager</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>employeeStateUtil</managed-bean-name>
<managed-bean-class>viewbean.EmployeeStateUtil</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>



HERE IS THE JAVA CODE AGAIN

/*RICHFACE COMMAND
Update function
<a4j:commandButton value = "update"
rendered = "#{rwwemployees.editable}"
action = "#{employeeStateUtil.setNewEmp()}" //model bean
reRender = "employeestateutiltable" //when the update button is clicked, render the new table
>
</a4j:commandButton> --> */


/*
THIS IS THE VIEWBEAN
Action employeeStateUtil.setNewEmp() is here:
*/


public void setNewEmp() throws SQLException{

EmployeeManager empmgr = (EmployeeManager)
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("employeeManager");

//THIS IS NULL!!!
//OTHER PROPERTIES OF THIS BEAN ARE NOT NULL
String newempinit = empmgr.getSelectedInitials();
}

//THIS IS THE CONTROLLER BEAN
//EmployeeManager is here:

public class EmployeeManager
{
private List<Employee> employees = new ArrayList<Employee>();
//private EmployeeDAO employeedao = new EmployeeDAO();

private String selectedInitials;
.....

public String getSelectedInitials() {
return selectedInitials;
}

//BEAN ISN"T GETTING SET!
public void setSelectedInitials(String selectedInitials) {
this.selectedInitials = selectedInitials;
}
}
ernest cronin
Greenhorn

Joined: Aug 23, 2012
Posts: 8
I'm using RichFaces 3.3
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15951
    
  19

The "code" tags go AROUND the code samples.

http://en.wikipedia.org/wiki/Inversion_of_control

BTW, it's also not a good idea to name a listener or action method "setXXXX". JavaBeans use "setXXX" and "getXXX" to set/get property values in the bean and property accessor/mutator methods should not be used to perform business functions or other actions with possible side-effects.

You also appear to be attempting to manually do something that JSF should be doing for you automatically, now that I look at it a little more closely (although so far, not too closely). JSF's IoC mechanism will automatically inject the values of the form controls into the Model (backing bean) without you having to write any JSF-specific code at all..
ernest cronin
Greenhorn

Joined: Aug 23, 2012
Posts: 8
I changed the action method name from set to avoid confusion as you suggested. So, using FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get() is not good JSF programming because it is hard-coded and, hence, lacks abstraction? But does this imply it will not work? I don't know what to do instead of using FacesContext and this may be an issue too large to resolve here. I tried just creating EmployeeManager object (instead of FacesContext) but still get null pointer.

So instead of:
EmployeeManager empmgr = (EmployeeManager)
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("employeeManager");
String newempinit = empmgr.getSelectedInitials();

i tried:
EmployeeManager empmgr = new EmployeeManager();
String newempinit = empmgr.getSelectedInitials();
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15951
    
  19

OK. Let's back up here and look at what you want to accomplish at a high level.

It appears that EmployeeManager is some sort of bean and you want that bean to be accessible in a JSF backing bean. I should point out, BTW that you say that EmployeeManager is a Controller, but in the JSF MVC implementation, you don't write your own Controllers, they are pre-supplied with JSF - you only provide Models and View templates.

If EmployeeManager is a JSF backing bean and it has a scope that is wider than the scope of the bean that is to receive it, you can simply wire the two beans together using the JSF ManagedProperty facility and JSF will do the rest - instantiate the beans and inject the EmployeeManager instance into the destination bean via the destination bean's "setEmployeeManager" property put method (which you code). All of that is automatic, and you don't need the FacesContext or any other JSF internals to do it, because IoC is about things being done for you from the outside in, not the inside out.
ernest cronin
Greenhorn

Joined: Aug 23, 2012
Posts: 8
Okay, I think I'm following you. Let's take one step back further. What I really want to do is set the variable (the employee's) selectedInitials in EmployeeManager. The method EmployeeStateUtil.selectNewEmp() (calls/uses/references/ what is the correct term?) the value of this bean property set by the ajax action function. So, i thought let me get rid of EmployeeStateUtil for now and just instantiate the property in EmployeeManager.
So, now the ajax action is:



This should then instantiate the bean by calling the setter method, getSelectedInitials(), correct?

I try to call a simple println in the method:



Now, I get this error:
HTTP Status 500 - #{employeeManager.selectedInitials}: javax.el.MethodNotFoundException: /employee/EmployeeStateUtil.xhtml @103,6 action="#{employeeManager.selectedInitials}": Method not found: controllerbean.EmployeeManager@22d89c.selectedInitials()

I don't understand how it cannot find it.
ernest cronin
Greenhorn

Joined: Aug 23, 2012
Posts: 8
The 'throws SQL Exception' isn't doing anything.
ernest cronin
Greenhorn

Joined: Aug 23, 2012
Posts: 8
Using the same code above, I tried to change the ajax function from action to binding= #{employeeManager.selectedInitials}. Now it is going into the setter. But here is the output of my println =

in getSI. si = null
in setSI. si = org.ajax4jsf.component.html.HtmlAjaxCommandButton@107940
in setSI. si = org.ajax4jsf.component.html.HtmlAjaxCommandButton@ba6400
in setSI. si = org.ajax4jsf.component.html.HtmlAjaxCommandButton@5b298

I have no idea why it's going into the setter 4 times.

if at any time this is becoming too complex, just let me know. you've given me some good info already.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 15951
    
  19

You told AJAX to call "selectedInitials", but you named the method "setSelectedInitials". AJAX methods are not get/set methods.

AJAX does not "set" the value. It submits the FORM that contains input control values. Those values are then validated by JSF, and if (and ONLY if) all values are valid, the backing bean is updated from the form control values and the ajax listener method is then invoked.

And yes, get/set methods can and will be invoked multiple times in the process of handling a JSF request/response lifecycle. Which is why they shouldn't have side-effects or attempt heavy processing.
ernest cronin
Greenhorn

Joined: Aug 23, 2012
Posts: 8
Tim, thank you. That really clears things up for me. I truly appreciate your time.
 
Don't get me started about those stupid light bulbs.
 
subject: my a4j:commandButton is failing suddenly, bean is no longer initialized, returning null value.
 
Similar Threads
Cannot find bean: "EMPLOYEELIST" in any scope
Hibernate Transaction Autocommit set to false
Spring sample applications - Need Help
Struts-tags.tld
Deleting Record in a Web Application.