java.lang.NullPointerException at org.primefaces.extensions.component.remotecommand.RemoteCommandRenderer.decode - jsf

On the Facelet, I try to use <pe:remoteCommand> to update backingbean value:
<pe:remoteCommand name="saveMapArea" process="#this" actionListener="#{defineMapArea.createMapArea}">
<pe:assignableParam name="areaString" assignTo="#{defineMapArea.tagMapArea.mapArea}"/>
<pe:assignableParam name="areaName" assignTo="#{defineMapArea.tagMapArea.name}" />
<pe:assignableParam name="castId" assingTo="#{defineMapArea.tagMapArea.castId}" />
</pe:remoteCommand>
castId value is retrieved from a dropdown list by jQuery when user clicks submit button, the code for dropdown list is:
<h:selectOneMenu id="area_assign_device">
<f:selectItem itemLabel="Select Icast" itemValue="" />
<f:selectItems value="#{defineMapArea.castList}" var="cast" itemLabel="#{cast.name}" itemValue="#{cast.castId}"/>
</h:selectOneMenu>
the code for submit button is:
<p:commandButton value="Submit" type="button" onclick="CreateArea.saveArea()"/>
the code for calling remotecommand 'saveMapArea' is:
saveArea : function() {
if(CreateArea.validate()) {
// ...some other code to init map area...
var name=jQuery('#area_name_text').val();
var castId=jQuery('#area_assign_device').val();
saveMapArea(mapArea, name, castId);
CreateArea.points = [];
}
}
and my backing bean is:
#ManagedBean
#RequestScoped
public class DefineMapArea extends BaseJsfBean {
private static final long serialVersionUID = 1L;
private static Log log = LogFactory.getLog(DefineMapArea.class);
private TagMapArea tagMapArea;
private List<TagMapArea> areaList;
private String areaListJson;
#ManagedProperty(value="#{tagCustomService}")
private ITagCustomService tagCustomService;
#Override
protected void init() throws Exception {
// ..some initializations...
}
public void createMapArea() {
log.info("Area Persisting : " + tagMapArea.getMapArea());
tagMapArea.setTagMapImageId(2);
tagMapArea.setMapAreaType("test");
tagMapArea.setDescription("test");
}
// ....all the getters and setters....
}
TagMapArea is the JPA entity, the part including castId field is:
#Column(name = "cast_id", nullable = false)
protected Integer castId;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="cast_id", nullable=false, insertable=false, updatable=false)
protected TagCast cast;
The problem is when I click submit button, it throws a NullPointerException like this:
java.lang.NullPointerException
at org.primefaces.extensions.component.remotecommand.RemoteCommandRenderer.decode(RemoteCommandRenderer.java:82)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1377)
at org.apache.myfaces.context.servlet.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:731)
at org.apache.myfaces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:214)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:932)
I'm pretty sure this is caused by castId field in the remote command, because if I remove that field, it works ok. I am confused why the selected value retrieved from the dropdown list doesn't get sent to the remotecommand. Does anyone konw where the problem is?

Still not sure where went wrong ,but i found a walk around, instead of using remote command in primefaces extentions, I tried the original remote command in primefaces and it works.
The code after change is:
<p:remoteCommand name="saveMapArea" actionListener="#{defineMapArea.createMapArea}" />
and for the javascript part, it becomes:
saveMapArea([{name:'mapArea', value:mapArea},{name:'name',value:name},{name:'castId',value:castId}]);
in the backing bean's createMapArea method, the code snippet to get values is:
FacesContext context = FacesContext.getCurrentInstance();
Map map = context.getExternalContext().getRequestParameterMap();
String mapArea = (String)map.get("mapArea");
String name = (String)map.get("name");
String castId = (String)map.get("castId");
log.info("Area Persisting : " + mapArea);
log.info("name: " + name + " castId: " + castId);

Related

How to Compare the values JSF selectonemenu

I am developing a JSF application
I have 2 selectOnemenu controls and submit button.
I need to disable the button if the values of 2 fields are equal
<h:selectOneMenu id="from" value="#{currencyBean.history.fromCurrency}" >
<f:selectItems value="#{currencyBean.currency}" var="c" itemValue="#{c}" itemLabel="#{c.name}"/>
</h:selectOneMenu>
<p:outputLabel for="to" value="to:" />
<h:selectOneMenu id="to" value="#{currencyBean.history.toCurrency}" >
<f:selectItems value="#{currencyBean.currency}" var="c" itemValue="#{c}" itemLabel="#{c.name}"/>
</h:selectOneMenu>
<p:commandButton id="calculateButton" value="Convert" update=":convert :historyPanel" onstart="PF('statusDialog').show()" onsuccess="PF('statusDialog').hide()" validateClient="true" ajax="true" action="#{currencyBean.Calculate()}" />
I tried to use onchange with ajax but everytime I change one dropdown the value of the second drowpdown became null in the backbean so I cannot read it.
Here is my backbean
#Named(value = "currencyBean")
#RequestScoped
public class CurrencyBean implements Serializable {
/**
* Creates a new instance of CurrencyBean
*/
private History history;
private Currency currency;
private Date currentDate;
#Inject
private Loginbean loginBean;
private List<History> historyList;
public List<History> getHistoryList() {
int userId = loginBean.getUserId();
if (userId != -1) {
return new HistoryHelper().GetHistoryListByUser(userId);
}
return null;
}
public CurrencyBean() {
history = new History();
}
public History getHistory() {
return history;
}
public void setHistory(History history) {
this.history = history;
}
public Currency[] getCurrency() {
return Currency.values();
}
public Date getCurrentDate() {
return new Date();
}
public void Calculate() {
int userId = loginBean.getUserId();
if (userId != -1) {
new CurrencyClient().Convert(userId, this.history);
}
}
}
any clue ?
My assumption is that all of your problems come from your managed bean scope. You have #Request scope so every request your managed bean will be removed from container, thus when you define onchange="submit()" (this is only my assumption because you haven't define how you implement onchange attribute) and you select value from one selectBox component values for this component is updated but the first one is still null. When you select second selectBox value updated from first selectBox doesn't exists anymore as managed bean has been removed after first request. You should try with wider scope for instance #ViewScope. If it doesn't help then further informations like implementation onchange attribute will be needed

Session Bean Data is lost after page reload or page change

I'm working on a JSF Project using a Wildfly 8 Server and jsf 2.2.
I've a web part with xhtml and beans + ejb part with models etc and a mysql database.
Part of Model (EJB part): Foo.java
String name = "";
Object Foo2 = new Foo2();
Part of Model (EJB part): Foo2.java
private static final long serialVersionUID = 1L;
String name = "";
Now I've input like this: input.xhtml
<f:metadata>
<f:event listener="#{ InputBean.init() }" type="preRenderView" />
</f:metadata>
<h:inputText
value="#{ InputBean.actualFoo.name }">
</h:inputText>
<h:selectOneMenu
value="#{InputBean.currentSelectedFoo2_ID}">
<f:selectItems value="#{InputBean.lhm_AllFoo2}" />
</h:selectOneMenu>
and a bean: InputBean.java
#SessionScoped
#ManagedBean(name = "InputBean")
public class InputBean implements Serializable
private static final long serialVersionUID = 1L;
private Long currentSelectedFoo2_ID;
private LinkedHashMap<String, Object> lhm_AllFoo2;
private Foo actualFoo;
public InputBean() {
lhm_AllPermissions = new LinkedHashMap<String, Object>();
actualFoo = new Foo();
}
public void init()
// Method of interface in EJB part which gives me all Foo2 to a list
List<Foo2> list_AllFoo2 = foo2Interface.getAllFoo2;
if ((list_AllFoo2 != null) && (list_AllFoo2.size() > 0)) {
for (Foo2 foo2 : list_AllBFoo2) {
lhm_AllFoo2.put(foo2.getName(), foo2.getId());
}
}
When I input data in the inputField and select data the selectonemenu and then reload the page (f5) or change to another page (of the same project) and go back the data in the input field is still avaiable but the selectonemenu is reseted to the default value.
I tried to debug the problem, but the data is already lost when the init is accessed, no setter of the bean is called before. The constructer isn't called too, so everything seems to be correct. The bean data which isn't linked to an input isn't lost too.
Is this a normal JSF problem and is there a way to solve that?

Using h:selectBooleanCheckbox with c:if to obtain row value of a <rich:datatable> - JSF

I'm using a <rich:datatable> to show the content of a List<Map<String, String>
In the code below, spotlightPtBindings is the List<Map<String, String> and spotlightbinding represents each Map<String, String>. In the first column, I'm showing one selectBooleanCheckBox for eah row. When a selectBooleanCheckBox is checked, I'd like to send the value of the Map<String, String> corresponding to the key "URI" as a parameter to the method: inserirBean.onSelectedCheckBox(uri), and that's why I put this value in a ui:param of name: uri. The problem here is that when I try to print the value uri received in inserirBean.onSelectedCheckBox(uri), I don't get the any output, as if it is empty. Below there's the rest of the code:
InsereDocumento.xhtml
<rich:dataTable value="#{inserirBean.spotlightPtBindings}" var="spotlightbinding">
<rich:column>
<f:facet name="header">*</f:facet>
<ui:param name="uri" value="#{spotlightbinding['URI']}"/>
<h:selectBooleanCheckbox value="#{selectionBean.selected}" />
<c:if test="#{selectionBean.selected}">
#{inserirBean.onSelectedCheckBox(uri)}"
</c:if>
</rich:column>
<c:forEach items="#{inserirBean.variableNamesPt}" var="vname">
<rich:column>
<f:facet name="header">#{vname}</f:facet>
#{spotlightbinding[vname]}
</rich:column>
</c:forEach>
</rich:dataTable> <br />
SelectionBean
package managedBeans;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
#ManagedBean
public class CheckBoxSelectionBean implements Serializable {
private transient boolean selected = false;
private static final long serialVersionUID = 1L;
public CheckBoxSelectionBean() {
// TODO Auto-generated constructor stub
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
InserirBean - I'm not showing here how the List<Map<String, String>> named spotlightPtBinding and how the List<String> variableNamesPt were populated, because it was a complex process, but I can tell you they are certainly populated, cause I can see their content on the screen.
#ManagedBean
public class InsereDocumentoBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<String> variableNamesPt = new ArrayList<String>();
private List<Map<String, String>> spotlightPtBindings = new ArrayList<Map<String, String>>();
public List<String> getVariableNamesPt() {
return variableNamesPt;
}
public List<Map<String, String>> getSpotlightPtBindings() {
return this.spotlightPtBindings;
}
public void onSelectedCheckBox(String uri) {
System.out.println("URI: " + uri);
}
}
What may the problem be? Thank you! I'm new to JSF and need your help!
In JSF rendering is a two-step process: there's view build time and view render time.
Although they're in the same file, some tags take effect at view build time, some at render time.
JSTL tags like <c:forEach>, <c:if> and all tag handlers (including <ui:param>, see here) are evaluated at view build time, they add content to the "final" xml tree that is then rendered by JSF.
JSF HTML tags and derivates like <rich:dataTable> are evaluated at view render time, so the datatable's var is evaluated later then the <ui:param> which causes spotlightbinding not to be bound when it's assigned to uri.
Instead, I suggest you assign an ajax listener to call the function:
<h:selectBooleanCheckbox value="#{selectionBean.selected}">
<f:ajax listener="#{inserirBean.onSelectedCheckBox(spotlightbinding['URI'])}" />
</h:selectBooleanCheckbox>
Note that the listener is called whenever the value changes.

Input fields hold previous values only if validation failed

I came up with a strange problem. I tried to isolate the problem so following is my simplified code.
public class MyBean {
private List<Data> dataList;
Data selectedData;
public MyBean() {
dataList = new ArrayList<Data>();
dataList.add(new Data("John", 16));
dataList.add(new Data("William", 25));
}
public List<Data> getDataList() {
return dataList;
}
public void edit(Data data) {
selectedData = data;
}
public void newData() {
selectedData = new Data(null, null);
}
public Data getSelectedData() {
return selectedData;
}
public class Data {
String name;
Integer age;
Data(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
}
xhtml:
<rich:modalPanel id="pop">
<h:form>
Name: <h:inputText value="#{myBean.selectedData.name}" required="true" id="txtName"/><br/>
Age : <h:inputText value="#{myBean.selectedData.age}" required="true" id="txtAge"/>
<a4j:commandButton value="Save"/>
<a4j:commandButton value="Close" onclick="Richfaces.hideModalPanel('pop');return false;"/>
<br/>
<rich:message for="txtName"/><br/>
<rich:message for="txtAge"/>
</h:form>
</rich:modalPanel>
<h:form>
<rich:dataTable value="#{myBean.dataList}" var="data">
<rich:column>#{data.name}</rich:column>
<rich:column>
<a4j:commandLink value="Edit" action="#{myBean.edit(data)}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/>
</rich:column>
</rich:dataTable>
<a4j:commandButton value="New" action="#{myBean.newData()}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/>
</h:form>
This is the path to error:
Load the page
Click the "Edit" link in first row(popup displays)
In popup, clear the "Age" field and click "Save".(Required message shown)
Click cancel(without filling "Age" field)
Click second link.
Now it shows irrelevant data(previous data). - This is the problem
Even when I click "New" button it shows incorrect data.
This happens only if a validation is failed in the popup.
Is there a solution for this?
This problem is in JSF 2 also recognized and explained in detail in the following answer: How can I populate a text field using PrimeFaces AJAX after validation errors occur? If you were using JSF 2, you could have used OmniFaces' ResetInputAjaxActionListener or PrimeFaces' <p:resetInput> or resetValues="true" for this.
To the point, you need to clear the state of the EditableValueHolder component when it's about to be ajax-rendered, but which isn't included in the ajax-execute. To clear the state, in JSF 2 you would have used the convenience method resetValue() for this, but this isn't available in JSF 1.2 and you need to invoke the 4 individual methods setValue(null), setSubmittedValue(null), setLocalValueSet(false), setValid(true) to clear the state.
To figure out which components are to be ajax-rendered, but aren't been ajax-executed, in JSF 2 you would have used PartialViewContext methods for this, but this is not available in JSF 1.2 which hasn't standardized ajax yet. You'd need to fiddle with RichFaces specific ajax API in order to figure that. I can't tell that from top of head, so here's a kickoff example assuming that you already know the components which needs to be cleared. Imagine that the form in your popup has id="popForm" and the name input field has id="nameInput", here's how you could clear it inside the newData() method:
UIInput nameInput = (UIInput) context.getViewRoot().findComponent("popForm:nameInput");
nameInput.setValue(null);
nameInput.setSubmittedValue(null);
nameInput.setLocalValueSet(false);
nameInput.setValid(true);
do one thing on cancel action set all popup values null. now in your next click all values set to be default.
or on click set all previous values null. and set all respective values after that.
I had the same problem. if you are using Primefaces, the solution is as simple as putting resetValues="true" on your p:commandLink or p:commandButton that loads the selected item.
After validation failed if you want to remain same as input data which you have pass as submission parameter, then set value attribute as your form bean name as mention below i.e.
<input type="text" id="fname" path="fname" value="${myFormBean.fname}"/>

Session Scoped Managed Bean constructor being called on each page refresh

I am using a session scoped managed bean for handling login in a Java EE application. After I authenticate the user, the user object is saved in this session bean. However, after I refresh the page, the session bean values are gone.
I was debugging the code and it results that the constructor of the session scoped managed bean is called again on page refresh, therefore initializing the user object with a new user. I guess this is not a normal behavior since it should be preserved on the session shouldn't it?
I am posting some parts of the login managed bean including the parameters and the login method. Basically the enteredEmail and enteredPassword stand for the entered data on the login form. If the authentication succeeds, the loggedIn boolean is turned to true and the logged in user object is stored in the checkedUser variable.
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class LoginController implements Serializable {
#EJB
private LoginSessionBean loginSessionBean;
#EJB
private LecturerFacade lecturerFacade;
private Lecturer checkedUser;
private String enteredEmail;
private String enteredPassword;
private boolean loggedIn;
/** Creates a new instance of loginController */
public LoginController() {
loggedIn = false;
checkedUser = new Lecturer();
}
public String login(){
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage msg = null;
this.setCheckedUser(lecturerFacade.findLecturerByEmail(enteredEmail));
if(loginSessionBean.checkPassword(checkedUser, enteredPassword))
{
loggedIn = true;
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome", checkedUser.getFirstName()+ " " + checkedUser.getLastName());
FacesContext.getCurrentInstance().addMessage(null, msg);
context.addCallbackParam("loggedIn", loggedIn);
}
return "Index";
I am also posting the two EJBs that the above managed bean uses. The lecturerFacade retrieves the user object with the entered email, while the loginSessionBean checks the password.
#Stateless
public class LecturerFacade extends AbstractFacade<Lecturer> {
#PersistenceContext(unitName = "EffectinetWebPU")
private EntityManager em;
Logger logger = Logger.getLogger("MyLog");
FileHandler fh;
protected EntityManager getEntityManager() {
return em;
}
public LecturerFacade() {
super(Lecturer.class);
}
public Lecturer findLecturerByEmail(String email) {
try {
return (Lecturer) this.getEntityManager().createQuery("SELECT l FROM Lecturer l WHERE l.email = :email").setParameter("email", email).getSingleResult();
} catch (NoResultException e) {
System.err.println("Caught NOResultException: "+ e.getMessage());
return null;
} catch (NonUniqueResultException e) {
System.err.println("Caught NonUniqueResultException: "+ e.getMessage());
return null;
} catch (IllegalStateException e) {
System.err.println("Caught IllegalStateException: "+ e.getMessage());
return null;
}
}
_
#Stateless
public class LoginSessionBean {
// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
#PersistenceContext(unitName = "EffectinetWebPU")
private EntityManager em;
protected EntityManager getEntityManager() {
return em;
}
public void setEntityManager(EntityManager em) {
this.em = em;
}
public boolean checkPassword(Lecturer user, final String enteredPassword) {
if (user.getPassword().equals(enteredPassword)) {
return true;
} else {
return false;
}
}
}
Please if someone has any suggestion of what is going wrong, please tell me
Im using glassfish 3.1 as application server and Primefaces as JSF library. Also, I have checked and the imported the sessionScoped annotation from the right package and not from javax.enterprise...
Your problem is thus here:
<p:menuitem value="Logout" ... onclick="#{loginController.logout()}"/>
The onclick attribute should represent a JavaScript handler function which is to be executed in the webbrowser when the enduser clicks the element. Something like
onclick="alert('You have clicked this element!')"
The onclick attribute also accepts a ValueExpression, so you can even let JSF/EL autogenerate its value accordingly:
onclick="#{bean.onclickFunction}"
with
public String getOnclickFunction() {
return "alert('You have clicked this element!')";
}
All the EL is thus evaluated when the page is rendered. In your particular case, the logout() method is called everytime the EL is evaluated and thus you're invalidating the session everytime the page is rendered!
You need to bind it to an attribute which takes a MethodExpression like <h:commandLink action>, <h:commandButton action> and in this particular case <p:menuitem action>.
<p:menuitem value="Logout" ... action="#{loginController.logout()}"/>
This can be understood by understanding basic HTML and JavaScript concepts and keeping in mind that JSF ultimately produces HTML/CSS/JS. Open the JSF page in webbrowser, rightclick and View Source to realize it.
Well I managed to solve it today. This was the problem, although I cannot explain why:
I was using Primefaces 3.2 as JSF library so this was the main menu of the index page.
<h:form>
<p:menubar >
<p:menuitem id="registerLink" value="Register" rendered="#{!loginController.loggedIn}" onclick="registerDialog.show()" />
<p:menuitem id="loginLink" value="Login" rendered="#{!loginController.loggedIn}" onclick="loginDialog.show()" />
<p:submenu label="Units" rendered="true">
<p:menuitem id="addNew" value="Add New" onclick="createUnitDialog.show()" />
<p:menuitem id="myUnits" value="My Units" onclick="" />
</p:submenu>
<p:menuitem id="results" value="Results/Statistics" rendered="#{loginController.loggedIn}" onclick=""/>
<p:menuitem id="profile" value="My Profile" rendered="#{loginController.loggedIn}" onclick=""/>
<p:menuitem id="logout" value="Logout" rendered="#{loginController.loggedIn}" onclick="#{loginController.logout()}"/>
</p:menubar>
</h:form>
After setting breakpoints to the whole code I discovered that the logout() method, which is supposed to destroy the managed bean, was called on every page refresh. I don't know why this happened as it should be called when the logout menuitem was clicked.
However, after changing the onclick="#{loginController.logout()} with action="#{loginController.logout()} the problem was solved.
I checked the documentation of Primefaces but nowhere this behavior was explained

Resources