Primefaces slected row id == null - jsf

I have a working datatable that can list out restaurant objects.
I want to delete/edite the selected ones but when I select one the following exception shows up:
org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!
Here is the table:
<h:form id="restaurantForm">
<p:dataTable var="restaurant"
value="#{restaurantLazyBean.lazyDataModel}" paginator="true"
rows="10" rowsPerPageTemplate="5,10,50" id="carTable" lazy="true"
selectionMode="single" selection="#{RestaurantEditBean.selected}"
rowKey="#{restaurant.id}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}">
<p:ajax event="rowSelect"
listener="#{RestaurantEditBean.onRowSelect()}"/>
<p:column headerText="ID">
<h:outputText value="#{restaurant.id}" />
</p:column>
</p:dataTable>
</h:form>
Now all ids appear in the table but on selection the exception shows up.
I tried to do everything according to the primefaces example. But they didn't even have the rowKey attribute.
Heres the bean if thats relevant.
#Named("RestaurantEditBean")
#ViewScoped
#EJB(name = "ejb.RestaurantService", beanInterface = RestaurantService.class)
public class RestaurantEditBean {
#EJB
private RestaurantService restaurantService;
private RestaurantDTO selected;
public void onRowSelect(SelectEvent event) {
selected = ((RestaurantDTO) event.getObject());
}
public RestaurantService getRestaurantService() {
return restaurantService;
}
public void setRestaurantService(RestaurantService restaurantService) {
this.restaurantService = restaurantService;
}
public RestaurantDTO getSelected() {
return selected;
}
public void setSelected(RestaurantDTO selected) {
this.selected = selected;
}
}
Primefaces: 5.3
JSF: 2.2

I found out that I did a terrible mistake.
In my LazyDataModel I had to override a function.
#Override
public RestaurantDTO getRowData(String rowKey) {
Long id = Long.parseLong(rowKey);
return restaurantService.findById(id);
}
The issue was cause by the previous Long.getLong(rowKey) and that one returned null.

Related

rowsPerPageTemplate Dropdown dissapears after selection change and clicking away

I have Datatables(PrimeFaces 8.0.1) on multiple pages, only one of them had rows and rowsPerPageTemplate attributes, now i need to modify all other DataTables in the same way. All DataTables (dataTableA,dataTableB,..) are almost identical and have own #SessionScoped Beans(ControllerA, ControllerB,..). At first all DataTables seem to be OK, but if i change the rows per page selection of a dataTableX and click away to another page/dataTable and then i turn back to dataTableX, rows per page dropdown isn't there anymore (for the rest of the session). Can anyone help please? Thank you.
listViewA.xhtml
<h:form id="listAUserForm">
<p:dataTable id="dataTableA"
value="#{controllerA.listA}"
reflow="true"
paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} #{msg.rows_per_page}: {RowsPerPageDropdown}"
currentPageReportTemplate="#{prop.current_page_report_template}"
paginatorAlwaysVisible="false"
var="entryA"
rows="#{controllerA.rowsPerPage}"
rowsPerPageTemplate="10,20,30,{ShowAll|'All'}"
rowKey="#{entryA}"
selection="#{controllerA.entriesSelected}">
<p:ajax event="rowSelectCheckbox" listener="#{controllerA.onRowSelect}" update=":toolbarA" />
<p:ajax event="rowUnselectCheckbox" listener="#{controllerA.onRowUnselect}" update=":toolbarA" />
<p:ajax event="toggleSelect" process="#this" partialSubmit="true" update=":toolbarA"/>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
....
....
</h:form>
ControllerA.java
#ManagedBean(name = "ControllerA")
#SessionScoped
public class ControllerA extends BaseController
{
private int rowsPerPage = 10;
private List<EntryA> entries= null;
public int getRowsPerPage()
{
return rowsPerPage;
}
public void setRowsPerPage(int rowsPerPage)
{
this.rowsPerPage = rowsPerPage;
}
public List<EntryA> getListA()
{
if (entries== null)
{
entries= new ArrayList<>();
List<EntryA> tmpListA;
try
{
tmpListA= getSecurityServiceLocator().getBeanA().getAllEntries();
}
catch (SecurityException ex)
{
LOGGER.error("Error retrieving listA", ex);
return Collections.emptyList();
}
if (!isFilterExist())
{
entries.addAll(tmpListA);
return entries;
}
for (EntryA tmpEntryA : tmpListA)
{
if (tmpEntryA.filterMatch(filterValue.toLowerCase()))
{
entries.add(tmpEntryA);
}
}
}
return entries;
}
...

How to check another checkbox when click first checkbox? My checkbox list retrieve from datafile

I am new in jsf. My checkbox list retrieve from datatable. if checkbox with documentId 101 selected, system should auto select another checkbox which documentId 102. How to code this problem?
<p:dataTable id="popup1" var="comp1" rows="10"
value="#{ExaBackingBean.managedBean.popupcomp1List}"
editable="true"
selection="#{ExaBackingBean.managedBean.popupcomp1Select}"
rowKey="#{comp1.documentId}" rowIndexVar="index">
<ac:paginator for="popup1"></ac:paginator>
<p:column style="width:3px;text-align:center;" >
<p:selectBooleanCheckbox value="#{comp1.selected}">
<p:ajax listener="#{ExaBackingBean.ckechboxSelectPairingAction(comp1.documentId)}" partialSubmit="true" process="#this" update="#([id$=CompChecklist])" />
</p:selectBooleanCheckbox>
</p:column>
// ExaBackingBean
public void ckechboxSelectPairingAction(int documentId) throws Exception {
if (documentId == 101) {
System.out.println("documentId test"+documentId);
--- checkbox101 & checkbox102 will check
}
First of all, you want to show many check boxes, then you should to use selectManyCheckbox instead of selectBooleanCheckbox.
Let's create pseudo example, how to choose some value depending other:
HTML clode
<p:selectManyCheckbox id="basic" value="#{bean.selectedItems}">
<f:selectItems value="#{bean.availableItems}" />
<p:ajax listener="#{bean.someLogic}" update="someComponent"/>
</p:selectManyCheckbox>
BackedBean
private Map<String, String> availableItems; // +getter (no setter necessary)
private List<String> selectedItems; // +getter +setter
#PostConstruct
public void init() {
availableItems = new LinkedHashMap<String, String>();
availableItems.put("Document1 label", "document1");
availableItems.put("Document2 label", "document2");
availableItems.put("Document3 label", "document3");
}
public void someLogic() {
boolean contains = selectedItems.contains("document1");
if (contains) {
selectedItems.add("document2");
}
}

How to use p:chart in a column of every row with a datatable

I would like to know if is possible to use a pie chart in a column of every row in a datatable and how to do it in JSF2.2 with primefaces showcase:
https://primefaces.org/showcase/ui/chart/pie.xhtml
My idea is to show a pie chart 100% with a color based in the id into a grid
for every row and a description.
1.blue
2.yellow
3.red.
etc...
I've try the basic code below from the showcase with no success and I have not found any similar example. My xhtml works fine but when I add the pie chart get an error.
#ManagedBean(name = "info")
#ViewScoped
public class InfoView implements java.io.Serializable {
#ManagedProperty(value = "#{infoBo}")
private InfoBo infoBo;
private Long id;
private String description;
private List<Info> listInfo;
private InfoDataModel infoDataModel;
private Info infoSelected;
private PieChartModel pieModel1;
#PostConstruct
public void init() {
createPieModels();
}
public PieChartModel getPieModel1() {
return pieModel1;
}
private void createPieModel() {
createPieModel1();
}
private void createPieModel1() {
pieModel1 = new PieChartModel();
pieModel1.set("Blue", 100);
pieModel1.setTitle("Blue Simple Pie");
pieModel1.setLegendPosition("w");
pieModel1.setShowDataLabels(true);
pieModel1.setDiameter(150);
}
public getters & setters {
}
View xhtlm:
<p:dataTable id="datatableInfo" var="varInfo" value="#{Info.infoDataModel}" widgetVar="wdatatableInfo" style="width: 98%"
paginator="true" paginatorPosition="bottom" rows="10" rowsPerPageTemplate="10,20,30,40,50"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
selectionMode="single" tableStyle="table-layout:fixed;width:120" >
<p:column id="id_Reg" headerText="ID" style="width: 2%" sortBy="#{varInfo.id}" >
<h:outputText value="#{varInfo.idReg}"/>
</p:column>
<p:column id="id_description" headerText="Description" style="width: 10%" >
<h:outputText value="#{varInfo.description}"/>
</p:column>
<p:column id="id_chart" headerText="Chart" style="width: 80%" >
<p:chart type="pie" model="#{varInfo.pieModel1}" style="width:40px;height:30px" />
</p:column>
Thanks.
It works fine, chart only appears (in my app) with pieModel1.setLegendPosition("s")

getting null row key after using primefaces filter

When i am not using filter in primefaces datatable and try to select row then for example press edit it working well and takes the selected row.but when i use primefaces filter and then select the filtered row then edit
i got org.primefaces.model.SelectableDataModel when selection is enabled exception.
i know that mean i have a null row key but i don't know why.i am using a valid row key(id) the primary key of the datatable and when i use the debug i found that it get the id two times in the failure case,first time it got the right filtered id and the second time it get null id.
my question why it gets the rowkey id two times which get the null in the second time and cause the exception
<h:body>
<h:form prependId="false" id="growlForm">
<p:growl id="growl" showDetail="false" />
</h:form>
<h:form id="dataForm">
<p:panel id="ingerdientsTable">
<f:facet name="header">
<h:outputText value="Standard Food List" />
</f:facet>
<p:dataTable id="ingedientsTable" widgetVar="ingedientsTable" var="ingerdients" resizableColumns="true"
selectionMode="single" selection="#{mealBean.selectedStandardIngerdients}"
rowKey="#{ingerdients.getId()}" value="#{mealBean.allIngerdients}" rowsPerPageTemplate="5,10,25,50" rows="20"
paginator="true" style="padding-top:10px;padding-bottom:10px" tableStyle="table-layout: auto"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown} ">
<p:column headerText="Food Type" filterBy="#{ingerdients.name}"><h:outputText value="#{ingerdients.name}" /></p:column>
<p:column headerText="Protein(gm)" filterBy="#{ingerdients.containedProtiens}"><h:outputText value="#{ingerdients.containedProtiens}" /></p:column>
<p:column headerText="Carbs(gm)" filterBy="#{ingerdients.containedCarbs}"><h:outputText value="#{ingerdients.containedCarbs}" /></p:column>
<p:column headerText="Fats(gm)" filterBy="#{ingerdients.containedFats}"><h:outputText value="#{ingerdients.containedFats}" /></p:column>
<p:column headerText="Total Calories" filterBy="#{ingerdients.totalCalories}"><h:outputText value="#{ingerdients.totalCalories}" /></p:column>
<p:column styleClass="action-column">
<f:facet name="header">
<h:outputText value="Actions" />
</f:facet>
<p:commandButton id="addToMeal" value="Add To Meal" icon="ui-icon-create" update="addToMealDialog"
action="#{mealBean.showIngerdientsToMealDialog(ingerdients)}" immediate="true"
title="Add To meal" ajax="true">
</p:commandButton>
<p:tooltip for="addToMeal" value="Add To Meal"
showEffect="fade" hideEffect="fade" />
</p:column>
</p:dataTable>
</p:panel>
public class StandardIngerdients{
#Id
#Column(name="Id")
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
#ManyToOne
#JoinColumn(name="FolderPathId",referencedColumnName="Id",nullable=true)
private FolderPath folderPath;
#Column(name="Name")
private String name;
#Column(name="ContainedProteins")
#NotNull
private Double containedProtiens;
#Column(name="ContainedCarbs")
#NotNull
private Double containedCarbs;
#Column(name="ContainedFats")
#NotNull
private Double containedFats;
#Column(name="TotalCalories")
#NotNull
private Double totalCalories;
#Column(name="ImageName")
private String imageName;
public Integer getId() {
return id;
}
public void setId(Integer Id) {
this.id = Id;
}
public FolderPath getFolderPath() {
return folderPath;
}
public void setFolderPath(FolderPath folderPath) {
this.folderPath = folderPath;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getContainedProtiens() {
return containedProtiens;
}
public void setContainedProtiens(Double containedProtiens) {
this.containedProtiens = containedProtiens;
}
public Double getContainedCarbs() {
return containedCarbs;
}
public void setContainedCarbs(Double containedCarbs) {
this.containedCarbs = containedCarbs;
}
public Double getContainedFats() {
return containedFats;
}
public void setContainedFats(Double containedFats) {
this.containedFats = containedFats;
}
public Double getTotalCalories() {
return totalCalories;
}
public void setTotalCalories(Double totalCalories) {
this.totalCalories = totalCalories;
}
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
}
I was having the same problem. The thing is I make my class to implement Serializable which guarantee the "integrity" (so to speak) of data in order not to disappear hehe... so your class would be like this:
public class StandardIngerdients implements Serializable {
you can try below code i think solve it
rowKey="#{ingerdients.id}"

CommandLink inside the datatable doesn't work in some cases

I have the CommandLink/CommandButton which is an element of the column in the dataTable. The dataTable is integrated with the lazy model. My code (not exactly my, because this is the primefaces showcase example) works perfect when the number of records in the table is divisible by the page size. For example the page size is 5 and the number of records is 60. But, when the number of records is 61, then when I reach the last record in the table, the action listener for every button is not called. I've tried to change p:commandlink to h:commandbutton/p:commandbuton. I've tried all the stackoverflow tips related to use update="#form" or immediate="true" or disable ajax requests by ajax="false", but the result is the same. For me it looks like a problem with dataTable rendering. Please look at the source code. This example is based on the primefaces showcase, I've added only a new column (this one with the commandlink).
xhtml page:
<h:form id="form">
<p:dataTable styleClass="test-class" id="data" var="car" value="#{tableBean.lazyModel}" scrollable="true" liveScroll="true" scrollRows="5" scrollHeight="200" lazy="true" >
<p:column headerText="Model">
<h:outputText value="#{car.model}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Manufacturer">
<h:outputText value="#{car.manufacturer}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<p:column headerText="Color">
<p:commandLink value="Test"
actionListener="#{tableBean.buttonListener()}" />
</p:column>
</p:dataTable>
</h:form>
datatable lazy model:
public class MyLazyModel extends LazyDataModel<Car> {
private List<Car> datasource;
public MyLazyModel(List<Car> datasource) {
this.datasource = datasource;
}
#Override
public Car getRowData(String rowKey) {
for(Car car : datasource) {
if(car.getModel().equals(rowKey))
return car;
}
return null;
}
#Override
public Object getRowKey(Car car) {
return car.getModel();
}
#Override
public List<Car> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {
//rowCount
int dataSize = datasource.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
return datasource.subList(first, first + pageSize);
}
catch(IndexOutOfBoundsException e) {
return datasource.subList(first, first + (dataSize % pageSize));
}
}
else {
return datasource;
}
}
}
DataTable bean:
#ManagedBean
#ViewScoped
public class TableBean {
private LazyDataModel<Car> lazyModel;
private Car selectedCar;
private List<Car> cars;
public TableBean() {
populateRandomCars(cars, 60);
lazyModel = new MyLazyModel(cars);
}
public void setSelectedCar(Car selectedCar) {
this.selectedCar = selectedCar;
}
public LazyDataModel<Car> getLazyModel() {
return lazyModel;
}

Resources