JPA JSF Assign value to a null object - jsf

Good Afternoon in my timezone.
I am working on a web application, that uses both JSF and JPA.
There is one screen that contains multiple checkBoxes , something like this:
option1 check1 check2
option2 check1 check2
option3 check1 check2
In the database the query to retrieve the values of the checkboxes uses one LEFT JOIN (this is business logic) to retrieve the checkbox values:
Select * FROM Option LEFT OUTER JOIN CheckBoxType ....
The class diagram is something like this:
class Option
String label
checkBoxType checkBox
class CheckBoxType
boolean value;
The final result is , it could exist a list of "Option" in which some contains the checkBox variable to NULL.
In the JSF we use the following code:
<ui:repeat var="assocCheck" value="#{checkBean.getOptions}">
<h:selectBooleanCheckBox name="#{assocCheck.label}" value="#{assocCheck.checkBox.value}"/>
</ui:repeat>
To present the results there is no problem, in the case of the "Option" objects that contains the checkBox to null the checkbox on the screen appers with NO value , when i set to true one of this checkboxes and try to save them, the JSF throws a exception telling me the following
javax.faces.component.UpdateModelException: javax.el.PropertyNotFoundException: ....xhtml #45,126 value="#{assocCheck.checkBox.value}": Target Unreachable, 'null' returned null
I understand why this is happening , what is the best manner to deal with a problem like this ?Could adding a valueChangeListener on the checkbox(every time a checkbox is full filled there is a method on the bean that creates the checkBox object) be the best approach ?
Thanks in advance
Best regards

I would use a lazy setter / getter in your Option class:
#Entity
public class Option {
#...ToOne(optional = true, ...)
private CheckboxType checkbox;
public boolean isCheckboxChecked() {
return checkbox != null && checkbox.getValue();
}
public void setCheckboxChecked(boolean checked) {
if (checkbox == null) {
if (!checked) {
// No need to create a CheckboxType
return;
}
checkbox = new CheckboxType();
}
checkbox.setValue(checked);
}
}
Now you can use that one in your JSF page:
<h:selectBooleanCheckBox name="#{option.label}" value="#{option.checkBoxChecked}"/>
Why I would use this approach: It keeps the business logic attached to the business object. Especially the implicit statement checkbox == null means the same as checkbox.value == false is made explicit.
BTW: I would rename Checkbox.value to Checkbox.checked - from my point of view it makes things clearer: checkbox.isChecked() vs. checkbox.getValue() (or even worse checkbox.isValue()).

Related

How do I extract the value of a UIInput in XPages

I have an Xpages application that manipulates Contracts. One procedure uses the Contract Type value in field "conService" to determine what must happen next. The code below does NOT produce any errors but third line does not seem to process any result and in fact does not even seem to process any line in the procedure after it. How do I extract the value of the conService? Thanks
UIInput uifield = (UIInput) JSFUtil.findComponent("conService");
String serviceName ="";
serviceName = uifield.getValue().toString();
You are almost there....
Once you have the UIInput object you can do either .getSubmittedValue() or .getValue() - depending on where in the JSF lifecycle you are. And then you just need to cast it to a String - instead of using toString().
So something like should do the trick:
UIInput uifield = (UIInput) JSFUtil.findComponent("conService");
String serviceName = (String)uifield.getValue();
To avoid having to thinkg about using getSubmittedValue or getValue I use a small utility method in my code:
ublic static Object getSubmittedValue(UIComponent c) {
// value submitted from the browser
Object o = null;
if (null != c) {
o = ((UIInput) c).getSubmittedValue();
if (null == o) {
// else not yet submitted
o = ((UIInput) c).getValue();
}
}
return o;
}
That just makes life a little less complicated ;-)
/John
Where possible, it's worth going directly to the datasource you're storing the value in. It's more efficient and easier to manage.
If you do need the value during Process Validation phase, for a converter or validator, you can use component binding to easily access the relevant component, at which point you can use getSubmittedValue() - because the value will not have been set yet. Here's a NotesIn9 from Tim Tripcony covering it http://notesin9.com/index.php/2014/05/22/notesin9-143-component-vs-value-binding-in-xpages/.

NullPointerException while displaying the same page after some taks in 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.

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.

Using h:outputFormat to message-format the f:selectItems of a h:selectOneRadio

I am having some trouble with using h:selectOneRadio. I have a list of objects which is being returned which needs to be displayed. I am trying something like this:
<h:selectOneRadio id="selectPlan" layout="pageDirection">
<f:selectItems value="#{detailsHandler.planList}" />
</h:selectOneRadio>
and planList is a List of Plans. Plan is defined as:
public class Plan {
protected String id;
protected String partNumber;
protected String shortName;
protected String price;
protected boolean isService;
protected boolean isOption;
//With all getters/setters
}
The text that must appear for each radio button is actually in a properties file, and I need to insert params in the text to fill out some value in the bean. For example the text in my properties file is:
plan_price=The price of this plan is {0}.
I was hoping to do something like this:
<f:selectItems value="<h:outputFormat value="#{i18n.plan_price}">
<f:param value="#{planHandler.price}">
</h:outputFormat>" />
Usually if it's not a h:selectOneRadio component, if it's just text I use the h:outputFormat along with f:param tags to display the messages in my .property file called i18n above, and insert a param which is in the backing bean. here this does not work. Does anyone have any ideas how I can deal with this?
I am being returned a list of Plans each with their own prices and the text to be displayed is held in property file. Any help much appreciated.
Thanks!
I am now able to resolve the above issue following the recommendation below. But now I have another question.
Each radio button item must display like this:
Click **here** to see what is included. The cost is XX.
Now the above is what is displayed for each radio button. The "here" needs to be a hyperlink which the user can click and should bring up a dialog box with more info.I can display the sentence above but how do I make the "here" clickable?
Since the above is what is displayed it is the label for SelectItem(Object value, String label) which is returned.
Any ideas much appreciated.
The value passed to <f:selectItems /> must be a list or array of type javax.faces.model.SelectItem.
You can set the output label in the constructor of the SelectItem. I imagine you can access your properties file from the backing bean. The method to get the SelectItems would look something like this:
public List<SelectItem> getPlanItems() {
List<SelectItem> list = new ArrayList<SelectItem>();
for (Plan plan : planList) {
String label = buildPlanPriceLabel(plan.getPrice());
list.add(new SelectItem(plan, label));
}
return list;
}
Leaving buildPlanPriceLabel as an exercise for the reader.

Resources