p:dataTable Not Editing - jsf

I'm trying to create a DataTables with Cell Editing with Click such as presented here : https://www.primefaces.org/showcase/ui/data/datatable/edit.xhtml
The problem I have is that the table won't take modifications into account.
I have no problem displaying the datas from the MySQL Database. The table is loaded correctly with no errors. When I try modifying a cell, it becomes an input as expected. But when I change the value and press enter, the cell goes back to it's original value. If I re-enter edit mode on that cell, my modification reappears. Not modifications are made in the Database.
I'm not very at ease with JSF and PrimeFaces and I'm surely missing something obvious.
Here is my code :
Managed Bean :
package Application;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import org.primefaces.event.CellEditEvent;
import org.primefaces.event.RowEditEvent;
#Named(value = "plantCtrl")
#ViewScoped
public class PlantCtrl implements Serializable {
#EJB
private PlantDAO plantDAO;
public PlantCtrl() {
}
#PostConstruct
public void init(){
}
public List<Plant> getPlants() {
return plantDAO.allPlants();
}
public PlantDAO getPlantDAO() {
return plantDAO;
}
public void setPlantDAO(PlantDAO plantDAO) {
this.plantDAO = plantDAO;
}
public void onRowEdit(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Plant Edited");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onRowCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Edit Cancelled");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if(newValue != null && !newValue.equals(oldValue)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cell Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
}
PlantDAO :
package Application;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
#Stateless
public class PlantDAO {
#PersistenceContext(unitName = "CarnivorousGardenPU")
private EntityManager em;
public List<Plant> allPlants() {
Query query = em.createNamedQuery("Plant.findAll");
return query.getResultList();
}
public void add(Plant p) {
em.persist(p);
em.flush();
}
public void edit(Plant p) {
em.merge(p);
em.flush();
}
public void remove(Plant p) {
em.remove(em.merge(p));
em.flush();
}
}
XHTML :
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Dashboard</title>
</h:head>
<h:body>
<ui:include src="inc/header.xhtml" />
<h:form id="plantAdminList">
<p:growl id="msgs" showDetail="true"/>
<p:dataTable id="plantsTable" var="plant" value="#{plantCtrl.plants}" editable="true" editMode="cell" widgetVar="cellPlants">
<f:facet name="header">
Cell Editing with Click and RightClick
</f:facet>
<p:ajax event="cellEdit" listener="#{plantCtrl.onCellEdit}" update=":plantAdminList:msgs, :plantAdminList:plantsTable" />
<p:column headerText="Id">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{plant.genusPlant}" /></f:facet>
<f:facet name="input"><p:inputText id="modelInput" value="#{plant.genusPlant}" style="width:96%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Price">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{plant.pricePlant}" /></f:facet>
<f:facet name="input"><p:inputText value="#{plant.pricePlant}" style="width:96%" label="Price"/></f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</h:form>
<ui:include src="/inc/footer.xhtml" />
</h:body>
</html>
Plant.java is generated automatically by Netbeans as an Entity Classes From Database. I'm not posting it for not overloading this post but if it is needed, don't hesitate to ask.

Modify few lines of your managed bean like this
//....
List<Plant> plants;
#PostConstruct
public void init(){
plants=plantDAO.allPlants();
}
public List<Plant> getPlants() {
return plants;
}
//....
and it will work as you want: when you change the value and press enter, the cell will reflect your changes.
Notice that:
if you want to persist changes to database you will need to modify your p:dataTable a bit and create additional logic in managed bean to detect modifications and to pass them to already existing plantDao.edit method. Minimum of coding would be:
Modify data table like this
p:dataTable id="plantsTable" var="plant" value="#{plantCtrl.plants}" editable="true" widgetVar="cellPlants">
<p:ajax event="rowEdit" listener="#{plantCtrl.onRowEdit}"
update=":plantAdminList:msgs, :plantAdminList:plantsTable" />
....
<p:column style="width:32px">
<p:rowEditor />
</p:column>
</p:dataTable>
Modify onEditMethod inside managed bean
public void onRowEdit(RowEditEvent event) {
Plant editedPlant = (Plant)event.getObject();
plantDAO.edit(plant);
FacesMessage msg = new FacesMessage("Plant Edited");
FacesContext.getCurrentInstance().addMessage(null, msg);
}

Related

How can I select multiple rows within dataTable in JSF

I am facing some problem to select multiple rows of h:dataTable. My code is below:
<h:dataTable value="#{reportBean.lstchalan}" var="chalan" >
<h:column >
<f:facet name="header">
<h:outputText value="Select" />
</f:facet>
<h:selectBooleanCheckbox value="#{reportBean.checked[chalan.issueNo]}" />
</h:column>
...
</h:dataTable>
<h:commandButton value="submit" action="#{reportBean.submit()}" />
and Below is my backing bean:
public class ReportBean {
List<ChalanVo> checkedItems = new ArrayList<ChalanVo>();
private Map<String, Boolean> checked = new HashMap<String, Boolean>();
........
public List<ChalanVo> getCheckedItems() {
return checkedItems;
}
public void setCheckedItems(List<ChalanVo> checkedItems) {
this.checkedItems = checkedItems;
}
public Map<String, Boolean> getChecked() {
return checked;
}
public void setChecked(Map<String, Boolean> checked) {
this.checked = checked;
}
public String submit() {
checkedItems = new ArrayList<ChalanVo>();
for (ChalanVo dataItem : lstchalan) {
if (checked.get(dataItem.getIssueNo())) {
checkedItems.add(dataItem);
checked.remove(dataItem.getIssueNo());
}
}}
}
But I am getting an exception when execute the line for (ChalanVo dataItem : lstchalan) . lstchalan is giving null.Could you please help me to understand where I am doing wrong?
Here is a working, simplified example:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named("test")
#ViewScoped
public class TestBean implements Serializable{
private static final long serialVersionUID = -1064219566884774973L;
private List<ChalanVo> lstChalans;
private Map<ChalanVo, Boolean> checkedItems = new HashMap<TestBean.ChalanVo, Boolean>();
public TestBean() {
lstChalans = new ArrayList<TestBean.ChalanVo>();
lstChalans.add(new ChalanVo("test1"));
lstChalans.add(new ChalanVo("test2"));
lstChalans.add(new ChalanVo("test3"));
}
public List<ChalanVo> getLstChalans() {
return lstChalans;
}
public void setLstChalans(List<ChalanVo> lstChalans) {
this.lstChalans = lstChalans;
}
public Map<ChalanVo, Boolean> getCheckedItems() {
return checkedItems;
}
public void setCheckedItems(Map<ChalanVo, Boolean> checkedItems) {
this.checkedItems = checkedItems;
}
public void save() {
System.out.println("save");
for (Entry<ChalanVo, Boolean> e : checkedItems.entrySet()) {
if (e.getValue()) {
System.out.println("checked: " + e.getKey().getIssueNo());
}
}
}
public class ChalanVo {
private String issueNo;
public ChalanVo(String issueNo) {
setIssueNo(issueNo);
}
public String getIssueNo() {
return issueNo;
}
public void setIssueNo(String issueNo) {
this.issueNo = issueNo;
}
}
}
With this xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head />
<h:body>
<h:form>
<h:dataTable value="#{test.lstChalans}" var="chalan">
<h:column>
<f:facet name="header">
<h:outputText value="Select" />
</f:facet>
<h:selectBooleanCheckbox value="#{test.checkedItems[chalan]}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Issue No" />
</f:facet>
<h:outputText value="#{chalan.issueNo}"/>
</h:column>
</h:dataTable>
<h:commandButton action="#{test.save()}" value="Submit" />
</h:form>
</h:body>
</html>
The save() method is able to list the selected items. I think your NullPointerException is unrelated to the checkbox thing. But anyway, you can do the selection like this.

Untoggle action resets checkboxes inside a <p:rowExpansion>

I have the datatable inside the rowExpansion and I can select rows of that table by means of checkboxes. I select some of them. But after I click on the row-toggler icon to untoggle inner table the event resets checkboxes in "false".
Can I avoid this behavior ?
Car Brand:
import java.util.List;
public class CarBrand {
private final String brandName;
private final List<CarModel> models;
private boolean selected;
public CarBrand(String brandName, List<CarModel> models) {
this.brandName = brandName;
this.models = models;
}
public String getBrandName() {
return brandName;
}
public List<CarModel> getModels() {
return models;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
Car Model:
public class CarModel {
private final String modelName;
private final int year;
private boolean selected;
public CarModel(String modelName, int year) {
this.modelName = modelName;
this.year = year;
}
public String getModelName() {
return modelName;
}
public int getYear() {
return year;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
CDI Managed Bean:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Named;
import org.primefaces.event.ToggleEvent;
import org.primefaces.model.Visibility;
#Named
#SessionScoped
public class Bean implements Serializable {
List<CarBrand> brands;
#PostConstruct
private void init() {
brands = new ArrayList<>();
List<CarModel> carModels;
carModels = new ArrayList<>();
carModels.add(new CarModel("CL 63 AMG", 2011, 1));
carModels.add(new CarModel("S-Class Coupe", 2014, 2));
carModels.add(new CarModel("AMG GTS", 2015, 3));
brands.add(new CarBrand("Mercedes", carModels));
carModels = new ArrayList<>();
carModels.add(new CarModel("M5 F10", 2012, 4));
carModels.add(new CarModel("M6 F13", 2012, 5));
carModels.add(new CarModel("X5 M", 2015, 6));
brands.add(new CarBrand("BMW", carModels));
carModels = new ArrayList<>();
carModels.add(new CarModel("Polo", 2012, 7));
carModels.add(new CarModel("Golf GTI", 2013, 8));
carModels.add(new CarModel("Golf R", 2015, 9));
brands.add(new CarBrand("Volkswagen", carModels));
}
public void onRowToggle(AjaxBehaviorEvent event) {
ToggleEvent toggleEvent = (ToggleEvent) event;
FacesMessage msg;
if (toggleEvent.getVisibility() == Visibility.VISIBLE) {
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Toggled", "Visibility:" + toggleEvent.getVisibility());
} else {
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Untoggled", "Visibility:" + toggleEvent.getVisibility());
}
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public List<CarBrand> getBrands() {
return brands;
}
}
and .xhtml
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<f:view>
<h:head>
<title>TEST</title>
</h:head>
<h:body>
<h:form id="testForm" prependId="true">
<p:growl id="growl"/>
<p:dataTable id="carsTable" value="#{bean.brands}" var="brand" style="width: 400px">
<p:ajax event="rowToggle" listener="#{bean.onRowToggle}" update="testForm:growl"/>
<p:column style="width: 20px">
<p:rowToggler/>
</p:column>
<p:column headerText="Brand">
<b><h:outputText value="#{brand.brandName}"/></b>
</p:column>
<p:rowExpansion>
<p:dataTable id="modelsTable" value="#{brand.models}" var="model">
<p:column headerText="Model">
<h:outputText value="#{model.modelName}"/>
</p:column>
<p:column headerText="Year">
<h:outputText value="#{model.year}"/>
</p:column>
<p:column style="width: 20px">
<f:facet name="header">
<p:selectBooleanCheckbox id="selectAll" value="#{brand.selected}" rendered="#{not empty brand.models}">
<p:ajax/>
</p:selectBooleanCheckbox>
</f:facet>
<p:selectBooleanCheckbox id="modelSelect" value="#{model.selected}">
<p:ajax/>
</p:selectBooleanCheckbox>
</p:column>
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
</h:form>
</h:body>
</f:view>
The problem is even worse than you mention. It is caused by the implementation of the toggle. If you see what is going on in the DOM, the expanded items get removed completely. When you toggle it back, the object are re-rendered.
For some reason text values are preserved, but the checkboxes get reverted to their original value.
The situation is worth though. If you do not expand the expansion, then the not rendered elements are not submitted, which for checkboxes means their values are changed to "false" no matter what was their original value.
You have basically two options:
move checkboxes outside the expansion
store their value using Javascript outside their expanded area

How can I inject a managed property in an ActionListener

I wanted process data from other bean, in ActionListener method, but it throw NullPointerException, so i try resafe instance of bean to next instance in init() method with #PostConstruct annotation, but it still throw NullPointerException. I know that can obtain bean throught FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(context, expression, expectedType);but is it possible throught #ManagedProperty? This is the code:
Login.java
package sklad;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedProperty;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
public class Login implements ActionListener{
private Osoba os;
#ManagedProperty(value="#{osoba}")
private Osoba osoba;
#PostConstruct
public void init(){
os = osoba;
}
#Override
public void processAction(ActionEvent a) throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("zprava", new FacesMessage(os.getId().toString() + " " + os.getHeslo()));
}
public Osoba getOsoba() {
return osoba;
}
public void setOsoba(Osoba osoba) {
this.osoba = osoba;
}
public Osoba getOs() {
return os;
}
public void setOs(Osoba os) {
this.os = os;
}
}
Osoba.java
package sklad;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
#ManagedBean
#SessionScoped
public class Osoba{
private Integer id;
private String heslo;
public Osoba(){}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getHeslo() {
return heslo;
}
public void setHeslo(String heslo) {
this.heslo = heslo;
}
}
login.xhtml
<!DOCTYPE html>
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>title</title>
<link rel="stylesheet" type="text/css" href="../styles/login.css" />
</h:head>
<h:body>
<p:growl id="growl" showDetail="true" life="3000" />
<p:panel id="panel_login" header="Přihlášení" styleClass="panel">
<p:panelGrid styleClass="panelGrid">
<h:form>
<p:row>
<p:column>
<h:outputText value="ID: " />
</p:column>
<p:column>
<h:inputText id="id_login" value="${osoba.id}" />
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputText value="Heslo: " />
</p:column>
<p:column>
<h:inputSecret id="heslo_login" value="${osoba.heslo}" />
</p:column>
</p:row>
<p:row>
<p:column colspan="2">
<h:commandButton id="btn_login" value="Přihlásit">
<f:actionListener type="sklad.Login"/>
</h:commandButton>
</p:column>
</p:row>
</h:form>
</p:panelGrid>
</p:panel>
</h:body>
</html>
The more traditional way of invoking an action listener is to use a method binding, like so:
#ManagedBean
#RequestScoped
public class Login {
...
public void doLogin(ActionEvent event){
// handle action
}
}
And then in the button:
<h:commandButton id="btn_login" value="Přihlásit" actionListener="#{login.doLogin}"/>
This approach has the benefit of turning Login into a ManagedBean, which will make it so the annotations on it will be processed by JSF - and that makes the #ManagedProperty annotation work as expected.

Selecting from p:dataTable list and show details to another p:dataTable list

I have a table showing list from a bean. When I click one of the rows, I want to view details from another bean list what would I write to value to second detail datatable list ?
Let say I have a bean of list students datatable containing name, surname and numbers, when I click a row, on the second datatable there is a bean list of student's address, city and country
Now I can System.out.print the adress detail of student when I click to row in student table but I can't show it on datatable
I'm asking how I can take the values to a datatable, what will be the value in datatable?
Thanks for your help
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<f:view>
<h:form id="form">
<p:dataTable id="users" var="user" value="#{userOS.osList}"
paginator="true" rows="10" rowKey="#{user.kisiid}"
selection="#{userOS.selectedOS}" selectionMode="single">
<f:facet name="header">
Kullanıcı detaylarını görmek için view butonuna tıklayınız
</f:facet>
<p:ajax event="rowSelect" listener="#{userOS.onRowSelect}" update=":form:display"
oncomplete="userDialog" />
<p:column headerText="Student No" sortBy="ogrencino"
filterBy="ogrencino" id="ogrencino">
<h:outputText value="#{user.ogrencino}" />
<f:param name="kid" value="#{userOS.osList.rowIndex}" />
</p:column>
<p:column headerText="Name" sortBy="ad" filterBy="ad" id="ad">
<h:outputText value="#{user.ad}" />
</p:column>
<p:column headerText="Surname" sortBy="soyad" filterBy="soyad"
id="soyad">
<h:outputText value="#{user.soyad}" />
</p:column>
<p:column headerText="Faculty" sortBy="altbirim.ad"
filterBy="altbirim.ad" id="altbirim">
<h:outputText value="#{user.altbirim.ad}" />
</p:column>
<p:column headerText="Department" sortBy="bolum.ad"
filterBy="bolum.ad" id="bolum">
<h:outputText value="#{user.bolum.ad}" />
</p:column>
<p:column headerText="Status" sortBy="ogrencidurum.ad"
filterBy="ogrencidurum.ad" id="ogrencidurum">
<h:outputText value="#{user.ogrencidurum.ad}" />
</p:column>
<f:facet name="footer">
</f:facet>
</p:dataTable>
<p:panel id="dialog" header="User Detail" widgetVar="userDialog">
<h:panelGrid id="panelgrid" columns="2" cellpadding="4">
<p:dataTable id="display" var="adres" value="#{userOS.adresList}">
<p:column headerText="Adres Tipi">
<h:outputText value="#{adres.AddressType}" />
</p:column>
<p:column headerText="Adres">
<h:outputText value="#{adres.Address}" />
</p:column>
<p:column headerText="İl">
<h:outputText value="#{adres.City}" />
</p:column>
<p:column headerText="Ülke">
<h:outputText value="#{adres.Country}" />
</p:column>
</p:dataTable>
</h:panelGrid>
</p:panel>
</h:form>
</f:view>
</h:body>
</html>
And KisiInfoProcess.java code :
package com.revir.process;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.primefaces.event.SelectEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.revir.managed.bean.AddressBean;
import com.revir.managed.bean.OgrenimSureciBean;
import com.revir.domain.Adres;
import com.revir.domain.AdresDAO;
import com.revir.domain.Kisi;
import com.revir.domain.KisiDAO;
import com.revir.domain.Kisiadresi;
import com.revir.domain.Ogrenimsureci;
import com.revir.domain.OgrenimsureciDAO;
import com.revir.domain.Ulke;
import com.revir.process.KisiInfoProcess;
#ManagedBean(name = "userOS")
#SessionScoped
public class KisiInfoProcess implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory
.getLogger(KisiInfoProcess.class);
private List<OgrenimSureciBean> osList;
private List<AddressBean> adresList;
private List<AddressBean> adresListesi;
public List<AddressBean> getAdresListesi() {
return adresListesi;
}
public void setAdresListesi(List<AddressBean> adresListesi) {
this.adresListesi = adresListesi;
}
private OgrenimSureciBean selectedOS;
private AddressBean selectedAdres;
public OgrenimSureciBean getSelectedOS() {
return selectedOS;
}
public void setSelectedOS(OgrenimSureciBean selectedOS) {
this.selectedOS = selectedOS;
}
public AddressBean getSelectedAdres() {
return selectedAdres;
}
public void setSelectedAdres(AddressBean selectedAdres) {
this.selectedAdres = selectedAdres;
}
public List<OgrenimSureciBean> getOsList() {
OgrenimsureciDAO ogrenimsureciDAO = new OgrenimsureciDAO();
List<OgrenimSureciBean> osList = new ArrayList<OgrenimSureciBean>();
for (Iterator i = ogrenimsureciDAO.findByMezunOgrenciler((short) 8)
.iterator(); i.hasNext();) {
Ogrenimsureci og = (Ogrenimsureci) i.next();
OgrenimSureciBean osBean = new OgrenimSureciBean();
osBean.setBolum(og.getBolum());
osBean.setAd(og.getKisiByKisiid().getAd());
osBean.setSoyad(og.getKisiByKisiid().getSoyad());
osBean.setAltbirim(og.getAltbirim());
osBean.setOgrencino(og.getOgrencino());
osBean.setKisiid(og.getKisiByKisiid().getKisiid());
osBean.setOgrencidurum(og.getOgrencidurum());
osList.add(osBean);
System.out.println("osBean : " + osBean.toString());
}
return osList;
}
public void setOsList(List<OgrenimSureciBean> osList) {
this.osList = osList;
}
public void onRowSelect(SelectEvent event) {
System.out.println("On Row Select Metodu çalıştı");
try {
getAdresList();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public List<AddressBean> getAdresList() throws Exception {
if (getSelectedOS() != null) {
log.debug("PersonalInfoProcess - getAddressInfo - Start");
List<AddressBean> adresList = new ArrayList<AddressBean>();
KisiDAO kisiDAO = new KisiDAO();
AdresDAO adresDAO = new AdresDAO();
Long kisiid = getSelectedOS().getKisiid();
System.out.println("kisiid :" + kisiid);
Kisi kisi = kisiDAO.findById(kisiid);
for (Iterator i = kisi.getKisiadresis().iterator(); i.hasNext();) {
Kisiadresi kisiAdresi = (Kisiadresi) i.next();
System.out.println("i :" + i);
Adres tmpAdres = adresDAO.findById(kisiAdresi.getId()
.getAdresid());
if (tmpAdres != null) {
AddressBean address = new AddressBean(kisiid);
if (tmpAdres.getAdresturu() == null) {
address.setAddressType(null);
} else {
address.setAddressType(tmpAdres.getAdresturu().getAd());
System.out.println("Adres Türü:" +tmpAdres.getAdresturu().getAd());
}
address.setAddress(tmpAdres.getAdres());
System.out.println("Şehir:" +tmpAdres.getAdres());
if (tmpAdres.getIl() == null) {
address.setCity(null);
} else {
address.setCity(tmpAdres.getIl().getAd());
System.out.println("Şehir:" +tmpAdres.getIl().getAd());
}
if (tmpAdres.getUlke() == null) {
address.setCountry(null);
} else {
address.setCountry(tmpAdres.getUlke().getAd());
System.out.println("Ülke:" +tmpAdres.getUlke().getAd());
}
adresList.add(address);
System.out.println("adres" + address);
System.out.println("adreslist" + adresList);
}
log.debug("PersonalInfoProcess - getAddressInfo - End / Returning");
}
}
return adresList;
}
public void setAdresList(List<AddressBean> adresList) {
this.adresList = adresList;
}
}

f:setPropertyActionListener always setting null

I'm trying to put the currently iterated <p:dataTable var> as a property of a managed bean using <f:setPropertyActionListener>. However, it is always set as null.
The view, dentistas.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<ui:composition template="/templates/template.xhtml">
<ui:define name="content">
<h:form id="formDentistas">
<p:growl autoUpdate="true" />
<p:commandButton icon="ui-icon-plus" value="Cadastrar"
id="cadastrar" oncomplete="dialogCadastrar.show()" />
<p:dataTable var="dentista" value="#{dentistaMB.dentistas}"
paginator="true" emptyMessage="Não foi encontrado nenhum registro"
rows="10" id="dataTableDentistas">
<f:facet name="header">Lista de Dentistas</f:facet>
<p:column headerText="Nome" sortBy="nome" filterBy="nome" id="nome"
width="200px">
#{dentista.pessoaFisica.nome}
</p:column>
<p:column headerText="Data Nascimento" sortBy="dataNascimento"
filterBy="dataNascimento" id="dataNascimento" width="60px">
#{dentista.pessoaFisica.dataNascimento}
</p:column>
<p:column headerText="CRO" sortBy="cro" filterBy="cro" id="cro"
width="60px">
#{dentista.cro}
</p:column>
<p:column headerText="Ações" style="width:50px;">
<p:commandButton value="Alterar" icon="ui-icon-pencil">
<f:setPropertyActionListener target="#{dentistaMB.selectedDentista}" value="#{dentista}" />
</p:commandButton>
<p:commandButton value="Remover" icon="ui-icon-trash"
actionListener="#{dentistaMB.deletar}">
<f:setPropertyActionListener target="#{dentistaMB.selectedDentista}" value="#{dentista}" />
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
<ui:include src="/tabelas/dialog_insert_dentista.xhtml" />
</ui:define>
</ui:composition>
</h:body>
</html>
The managed bean, DentistaMBImpl:
package br.com.odontonew.mb;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.convert.FacesConverter;
import javax.faces.event.ActionEvent;
import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import br.com.odontonew.bean.Dentista;
import br.com.odontonew.bean.EstadoCivil;
import br.com.odontonew.bean.PessoaFisica;
import br.com.odontonew.bean.Sexo;
import br.com.odontonew.bean.SituacaoPessoa;
import br.com.odontonew.bean.Uf;
import br.com.odontonew.bo.BasicBO;
import br.com.odontonew.exception.BOException;
#ManagedBean(name = "dentistaMB")
#ViewScoped
public class DentistaMBImpl extends BasicMBImpl {
private Logger logger = Logger.getLogger(DentistaMBImpl.class);
#ManagedProperty("#{dentistaBO}")
private BasicBO dentistaBO;
private Dentista dentista;
private Dentista selectedDentista;
private List<Dentista> dentistas;
// Lists
private List<EstadoCivil> estadosCivis;
private List<SituacaoPessoa> situacoesPessoa;
private List<Sexo> sexos;
private List<Uf> ufs;
#PostConstruct
public void init() {
dentista = new Dentista();
dentista.setPessoaFisica(new PessoaFisica());
dentista.getPessoaFisica().setSexo(new Sexo());
dentista.getPessoaFisica().setEstadoCivil(new EstadoCivil());
dentista.getPessoaFisica().setSituacao(new SituacaoPessoa());
dentista.getPessoaFisica().setUf(new Uf());
estadosCivis = (List<EstadoCivil>) dentistaBO
.findByNamedQuery(EstadoCivil.FIND_ALL);
situacoesPessoa = (List<SituacaoPessoa>) dentistaBO
.findByNamedQuery(SituacaoPessoa.FIND_ALL);
sexos = (List<Sexo>) dentistaBO.findByNamedQuery(Sexo.FIND_ALL);
ufs = (List<Uf>) dentistaBO.findByNamedQuery(Uf.FIND_ALL);
}
public void salvar(ActionEvent event) {
try {
dentista = (Dentista) dentistaBO.save(dentista);
addInfoMessage("Dentista salvo com sucesso");
RequestContext.getCurrentInstance().execute(
"dialogCadastrar.hide()");
} catch (BOException e) {
addErrorMessage(e.getMessage());
}
}
public void atualizar(ActionEvent event) {
try {
dentistaBO.update(selectedDentista);
addInfoMessage("Dentista atualizado com sucesso");
} catch (BOException e) {
addErrorMessage(e.getMessage());
}
}
public void deletar(ActionEvent event) {
try {
dentistaBO.delete(selectedDentista);
addInfoMessage("Dentista deletado com sucesso");
} catch (BOException e) {
addErrorMessage(e.getMessage());
}
}
public List<Dentista> getDentistas() {
try {
if (dentistas == null)
dentistas = (List<Dentista>) dentistaBO
.findByNamedQuery(Dentista.FIND_ALL_COMPLETO);
return dentistas;
} catch (BOException e) {
addErrorMessage(e.getMessage());
return null;
}
}
/* gets and sets */
public Dentista getSelectedDentista() {
return selectedDentista;
}
public void setSelectedDentista(Dentista selectedDentista) {
this.selectedDentista = selectedDentista;
}
public Dentista getDentista() {
return dentista;
}
public void setDentista(Dentista dentista) {
this.dentista = dentista;
}
public Logger getLogger() {
return logger;
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public List<EstadoCivil> getEstadosCivis() {
return estadosCivis;
}
public void setEstadosCivis(List<EstadoCivil> estadosCivis) {
this.estadosCivis = estadosCivis;
}
public List<SituacaoPessoa> getSituacoesPessoa() {
return situacoesPessoa;
}
public void setSituacoesPessoa(List<SituacaoPessoa> situacoesPessoa) {
this.situacoesPessoa = situacoesPessoa;
}
public List<Sexo> getSexos() {
return sexos;
}
public void setSexos(List<Sexo> sexos) {
this.sexos = sexos;
}
public void setDentistas(List<Dentista> dentistas) {
this.dentistas = dentistas;
}
public List<Uf> getUfs() {
return ufs;
}
public void setUfs(List<Uf> ufs) {
this.ufs = ufs;
}
public BasicBO getDentistaBO() {
return dentistaBO;
}
public void setDentistaBO(BasicBO dentistaBO) {
this.dentistaBO = dentistaBO;
}
}
Here,
<p:commandButton value="Remover" icon="ui-icon-trash"
actionListener="#{dentistaMB.deletar}">
<f:setPropertyActionListener target="#{dentistaMB.selectedDentista}" value="#{dentista}" />
</p:commandButton>
you're performing the delete in an actionListener method instead of an action method. This is not right. Business actions should be performed in the action method. All action listeners, including the <f:setPropertyActionListener>, are invoked before action method in the very same order as they are declared and assigned on the command component. So, in effects, the delete is first invoked and then the property is set. That explains why the property is null during the delete.
The fix is simple: make it a real action method:
<p:commandButton value="Remover" icon="ui-icon-trash"
action="#{dentistaMB.deletar}">
<f:setPropertyActionListener target="#{dentistaMB.selectedDentista}" value="#{dentista}" />
</p:commandButton>
Don't forget to remove the ActionEvent argument:
public void deletar() {
// ...
}
See also:
Differences between action and actionListener
Unrelated to the concrete problem, if you happen to target a Servlet 3.0 / EL 2.2 compatible container, then you can even get rid of that <f:setPropertyActionListener> altogether:
<p:commandButton value="Remover" icon="ui-icon-trash"
action="#{dentistaMB.deletar(dentista)}" />
With:
public void deletar(Dentista selectedDentista) {
// ...
}
See also point 3 of How can I pass selected row to commandLink inside dataTable?

Resources