NullPointerException while displaying the same page after some taks in jsf - jsf

First I want to tell :
I saw How to use JSF's h:selectBooleanCheckbox with h:dataTable to create one object per row?
and my problem is like same but not solved problem.
Following is my code :
*.xhtml
<rich:column>
<h:selectBooleanCheckbox id="resolveTxn" value="#{verifyTransactionBean.checked[verifyTxnList.id]}"/>
</rich:column>
.
.//Some code here
.
<h:commandButton value="Resolve" action="#{verifyTransactionBean.resolveToTxn}" styleClass="btn" />
and following is my code
private Map<Long, Boolean> checked = new HashMap<Long, Boolean>();
public void resolveToTxn() {
List<ToVerifyTxnDTO> list = new ArrayList<ToVerifyTxnDTO>();
for (ToVerifyTxnDTO dTO : toVerifyTxnDTOList) {
if(checked.get(dTO.getId())){//I got null pointer exception here
Long id=dTO.getId();
verifyTransactionSessionBeanLocal.updateResolvedflag(id);
}
}
}
What I want to do ?
I want to pass checked row id as parameter on following :
verifyTransactionSessionBeanLocal.updateResolvedflag(id);
And after clicking the button Resolve some operation should be done and refresh dataTable and display same page. Operation is done but getting null pointer exception while displaying (Reddering) the same page
Thanks

The if () test on a Boolean will throw NullPointerException if the Boolean itself is actually null instead of true or false. In other words, the checked.get(dTO.getId()) has unexpectedly returned null for some reason.
That can have several causes:
The JSF implementation hasn't properly updated the checked map with the value from <h:selectBooleanCheckbox> for some reason.
The EL implementation was using Boolean instead of boolean for some reason.
The toVerifyTxnDTOList has incompatibly changed during the process which caused that the currently iterated dTO isn't the one which was been displayed in the table at the moment checkboxes were clicked (perhaps because the bean is request scoped instead of view scoped).
The toVerifyTxnDTOList contains more items than present in the checked map because you're using pagination and displaying only a subset at once.
In any case, to fix the NullPointerException, just add an additional nullcheck:
Boolean dtoChecked = checked.get(dTO.getId());
if (dtoChecked != null && dtoChecked) {
// ...
}
This however doesn't fix the underlying cause of your problem. My best guess would be that the toVerifyTxnDTOList contains more items than actually being displayed in the table. Thus, it's one of the last mentioned two causes mentioned in the list. The first mentioned two causes are theoretically possible, but in practice I haven't seen this before.

Related

Primefaces: how to update a p:inputText with a parameter on the setter? [duplicate]

This question already has answers here:
How to set a Map value in h:inputText
(1 answer)
Write to a map property in an h:inputText in h:dataTable
(1 answer)
Closed 4 months ago.
I have a page where the user must input grading for a number of categories. The categories are retrieved dynamically from a database (there are different user types, and for each type you get different categories). As there are subcategories, I have implemented it using <p:treeTable>.
I have the grades stored in a map, with the category id as the key and the grade as the value:
HashMap<Integer, Double> detailedGrades
The problem is how to get and set the grade for each category using <p:inputText>, because the category id has to be a parameter in that. I have managed to do the getter like this:
<p:inputText id="cat" value="#registerCandidateGradeBean.getGradeForCat(gradingCat.pkCertGradeCategoryId)}"/>
and in the bean:
public Double getGradeForCat(int catID){
return detailedGrades.containsKey(catID) ? detailedGrades.get(catID) : null;
}
This displays the value in the input field OK, but I don't know how to set the value when the user changes it. I tried with <p:ajax listener> as mentioned here, where I set
<p:ajax listener="#{registerCandidateGradeBean.setGradeForCat1(gradingCat.pkCertGradeCategoryId)}"/>
and in the bean:
public void setGradeForCat1(int catID){
System.out.println(catID);
}
but whenever I change the input value I get a "javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation" exception. I tried to use a valueChangeListener on the inputText
<p:inputText id="cat" value="#registerCandidateGradeBean.getGradeForCat(gradingCat.pkCertGradeCategoryId)}"
valueChangeListener="#{registerCandidateGradeBean.setGradeForCat}"/>
and in the bean:
public void setGradeForCat(ValueChangeEvent e){
System.out.println("called");
//System.out.println(catID);
System.out.println(e.getNewValue());
}
but it never gets called. (I have tried both setGradeForCat(ValueChangeEvent e) and setGradeForCat(ValueChangeEvent e, int catID)).
Any ideas?
Forgot to mention: we are using primefaces 5.3.
The problem is, that you use value="#registerCandidateGradeBean.getGradeForCat(gradingCat.pkCertGradeCategoryId)}" in the input component.
This makes jsf looking for a getter and setter which is called getgetGradeForCat and setgetGradeForCat.

How to specify the order of evaluation in JSF?

I'm on JSF-2.1_29. As far as I can see, the order of manged bean's methodw invokation corresponds to how they are placed in the markup. In my particular case I have:
<h:outputText value="Rows count:"/>
<h:outputText value="#{bonusBean.rowsCount}"/>
<rich:dataTable id="bonusesTable"
var="bonus"
value="#{bonusBean.list}"
render="ds"
rowClasses="tr0, tr1">
<!-- Columns, etc... -->
</rich:dataTable>
ManagedBean itself:
public class BonusBean{
private Integer rowsCount = 0;
//GET, SET
public List<BonusActionDTO> getList(){
List<BonusActionDTO> lst = new ArrayList<BonusActionDTO>();
//Getting the list from a persistance storage
rowsCount = lst.size();
return lst;
}
In that case getRowsCount() is being invoked first which returns 0, so the Rows count: 0 is going to be printed when the page is loaded first, although the table may contain some rows. After invokation of getRowsCount() method, getList() is being invoked, so the actual Rows count is going to printed only after refreshing the page. How can I reorder that order of methods invokation? Is it possible in JSF?
I don't know if you can change the order of the getter invocations. But apart of this, the dependency of the result of a get method on the call of another get method is a bad design. Two getter should return the same results without regard of the order in which they are called.

NullPointerException when executing same action multiple times

In my xhtml page, I have a search button and a p:datatable to display the search results. I added a c:if condition to hide and display the datatable.
<c:if test="#{!search_bean.isResultList}">
In my managedBean, I created the flag isResultEmpty and set it to true in my doInit(). In the action of my search button (actSearchForData), I've set it to true if my List is not empty.
private String actSearchForData() throws Exception {
if(resultList.size > 0) {
isResultEmpty = false;
}
}
Now this works without any errors the first time I execute actSearchForData and my resultList is displayed. But when I try to run actSearchForData the second time, I encounter nullpointer exception. I've tried debugging by returning isResultEmpty = true after getting the resultList but this only causes my flag to always return isResultEmpty = true.
How can I execute my search function multiple times and display the results in the datatable without getting any nullpointer exceptions?
UPDATE: I've tried using render again this time for the flag like rendered="!#{search_bean.isResultEmpty}". I no longer get nullpointerexception and my result list count displays the correct number of results but my data table does not show.
The JSF way to control conditional rendering is to use the rendered attribute like
<p:dataTable id="..."
value="#{search_bean.resultList}"
var="..."
rendered="#{not empty search_bean.resultList}" />
This will not render the datatable if resultList is null or resultList.size() is 0.
you must be getting NullPointerException (maybe) - because your "resultList" is null and still you are executing "resultList.size" inside "if(..)" statement
try something like This...
private String actSearchForData() {
if(resultList==null || resultList.size>0) {
isResultEmpty=false;
}
}
This code executes "isResultEmpty=false" - if(resultList is null)
Hope this works for you...

Is this a bug in primefaces autocomplete?

I'm trying to put an autocomplete that fetches suggestions as a list of Entry<String, Integer>
<p:autoComplete completeMethod="#{suggester.suggestTopics}"
var="x1" itemLabel="#{x1.key}" itemValue="#{x1.value.toString()}"
value="#{topicController.selected}" />
Manged bean code is as follows:
private int selected;
public int getSelected() {
return selected;
}
public void setSelected(int selected) {
this.selected= selected;
}
But this fails saying the Integer class doesn't have method/property named key. If I remove the value attribute from autocomplete then it starts working properly. But when I put value attribute it starts expecting that the object inside var should be of the same type as that inside value attribute. I believe/expect it should be that the object inside itemValue should be of the same type as that inside value attribute.
I want to use POJOs for suggestions but pass just the entity Id to the value
Using :
Primefaces 3.1
JSF 2.1.6
I believe/expect it should be that the object inside itemValue should
be of the same type as that inside value attribute.
Yes this makes sense, and it is the same in the primefaces showcase:
<p:autoComplete value="#{autoCompleteBean.selectedPlayer1}"
id="basicPojo"
completeMethod="#{autoCompleteBean.completePlayer}"
var="p" itemLabel="#{p.name}" itemValue="#{p}"
converter="player" forceSelection="true"/>
As you see is var="p" and itemValue="#{p} where p is an instance of Player. And selectedPlayer1 is also an instance of Player.
I don't know if it works with a Map since the Primefaces example is called "Pojo support" and the suggestions should be a List of elements of the same type as in the value attribute.
I think you want to use the Simple auto complete , but instead you looked at the wrong example on the showcase of the Pojo Support
x1 refers to the int selected - while it expect to be referred to a POJO (with key and value properties.) , that's why you get the message
Integer class doesn't have method/property named key
Or simple use the Simple auto complete
As commented to Matt you dont need to rebuild Player(Pojo) from Db. You can set simply id property of Player(Pojo) and in action method may be utilize this id to fetch it from DB.
In your case in convertor you might do
Entry<String, Integer> e = new Entry<String, Integer>();
e.setId(value) // where value is passed in to convertor in method getAsObject.....
This value will be set to private Entry<String, Integer> selected
I have used Pojo autocomplete but not tried with generic classes.
Hope this helps.
I know the question is outdated but I've had the same problem.
The point is that you have to assign var to p (var="p"). I think it's terribly unobvious (documentation doesnot mention it has to be that way) 'cause I thought I can assign any var name I want.

Bind the value of an input component to a list item by index

here is an example :
<h:outputLabel for="category1" value="Cateogry"/>
<h:selectOneMenu id ="category1" value="#{articleManageBean.categoryId1}"
converter="categoryConverter">
<f:selectItems value="#{articleManageBean.categories}" var="category"
itemValue="#{category.id}" itemLabel="#{category.name}" />
</h:selectOneMenu>
and here is the managed bean that I have
#ManagedBean
#SessionScoped
public class ArticleManageBean {
private Long categoryId1;
private List<Category> categories;
//...
}
The categories list gets populated from db, and selectOneMenu gets populated with this list using a converter.
My First question:
If I want to create another selectOneMenu in my jsf page I would have to copy paste the entire thing and just change the value of selectOneMenu to say categoryId2 thus putting another attribute to managed bean called categoryId2. That is not practical. I want to map these values of selectMenu to list items, for instance to an attribute
List<Long> categoryIds;
if I use
<h:selectOneMenu id ="category1" value="#{articleManageBean.categoryIds.[0]}" >
I get an error
javax.el.PropertyNotFoundException: /createArticle.xhtml #47,68 value="#{articleManageBean.categoriesId[0]}": Target Unreachable, 'null' returned null
If I nitialize the Araylist then I get this exception
javax.el.PropertyNotFoundException: /createArticle.xhtml #47,68 value="#{articleManageBean.categoriesId[0]}": null
My second question:
Is there a way to dinamicly write selectOneMenu tags, by that I mean not to copy paste the entire tag, just somehow create a function that take the categoryId parameter and writes automaticaly the tag (somekind of custom tag maybe ?)
Hope you understood my questions
thanks in advance
Use the brace notation instead to specify the index.
<h:selectOneMenu id="category1" value="#{articleManageBean.categoryIds[0]}">
You only need to make sure that you have already prepared the values behind #{articleManageBean.categoryIds}. JSF won't do that for you. E.g.
private List<Long> categoryIds = new ArrayList<Long>();
public ArticleManageBean() {
categoryIds.add(null);
categoryIds.add(null);
categoryIds.add(null);
// So, now there are 3 items preserved.
}
an alternative is to use Long[] instead, this doesn't need to be prefilled.
private Long[] categoryIds = new Long[3]; // So, now there are 3 items preserved.

Resources