How to do CRUD operation with PrimeFaces datatable - jsf-2

I have one datatable created with a PrimeFaces 3.3 datatable. This table is populated from a database.
On a row selection, I populate similar fields for editing. Once edited, I want to write to the db. Similarly, I want to be able to create a new record in text items and once the user saves it the datatable to be refreshed.
Data selection works fine, however, when I cant figure out way for add/edit/delete, different errors come with different approach and I have tried all methods I could find on Google. These errors are some time logical errors and some times nullpointerexception or class initiation errors. I have tried over a dozen examples available on net for jtable + crud but seems nothing works fine for me.
For example, data is displayed in data table and instant selection in the text fields is also done but when i click add button, nothing happens, I expect fields in 'edit properties' panel to be cleared, sometimes I get a NullPointerException, even if I modify values in text items and press save, values are not written. When I debugged, I found error coming in em.getTransaction().begin line.
If I use em.joinTransaction it again throws an error on the commit statement. Since I am new to Java EE I think I am making some terrible mistakes.
I will appreciate if some one can give some example of a similar scenario: jtable + bound fields + add / edit / delete operations.
below is my code:
#Entity
#Table(name = "users")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
#NamedQuery(name = "Users.findByIduser", query = "SELECT u FROM Users u WHERE u.iduser = :iduser"),
#NamedQuery(name = "Users.findByLogin_Name", query = "SELECT u FROM Users u WHERE u.login_name = :login_name"),
#NamedQuery(name = "Users.findByFullName", query = "SELECT u FROM Users u WHERE u.fullName = :fullName"),
#NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password"),
#NamedQuery(name = "Users.authenticate", query = "SELECT u FROM Users u WHERE u.login_name = :login_name and u.password = :password and u.active=1"),
#NamedQuery(name = "Users.findByActive", query = "SELECT u FROM Users u WHERE u.active = :active"),
#NamedQuery(name = "Users.findByUserType", query = "SELECT u FROM Users u WHERE u.userType = :userType"),
#NamedQuery(name = "Users.findByEmail", query = "SELECT u FROM Users u WHERE u.email = :email"),
#NamedQuery(name = "Users.findByPhone", query = "SELECT u FROM Users u WHERE u.phone = :phone"),
#NamedQuery(name = "Users.findByCreated", query = "SELECT u FROM Users u WHERE u.created = :created"),
#NamedQuery(name = "Users.findByUpdated", query = "SELECT u FROM Users u WHERE u.updated = :updated")})
public class Users implements Serializable {
#Basic(optional = false)
#NotNull
#Column(name = "created")
#Temporal(TemporalType.TIMESTAMP)
private Date created;
#Basic(optional = false)
#NotNull
#Column(name = "updated")
#Temporal(TemporalType.TIMESTAMP)
private Date updated;
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO )
#Basic(optional = false)
#NotNull
#Column(name = "iduser")
private Integer iduser;
//getter & setters ....
#Stateless
public class UsersFacade extends AbstractFacade<Users> {
#PersistenceContext(unitName = "VUProjectPU")
private EntityManager em;
///////////////////////////////////////////////////////////////////////////////
#Override
protected EntityManager getEntityManager() {
return em;
}
///////////////////////////////////////////////////////////////////////////////
public UsersFacade() {
super(Users.class);
}
///////////////////////////////////////////////////////////////////////////////
public Users authenticate(String login_id, String pwd) {
List <Users> userList = new ArrayList();
Users user =null;
userList = em.createNamedQuery("Users.authenticate")
.setParameter("login_name", login_id)
.setParameter("password", pwd)
.getResultList();
if (userList.isEmpty()) {
return null;
}
else{
user = userList.get(0);
}
return user;
}
///////////////////////////////////////////////////////////////////////////////
public Users deactivateUser (Users u){
u.setActive(false);
return u;
}
///////////////////////////////////////////////////////////////////////////////
public Users activateUser (Users u){
u.setActive(true);
return u;
}
///////////////////////////////////////////////////////////////////////////////
public Users createAnalyst(Users u){
u.setActive(false);
u.setUserType("Analyst");
u.setCreated(new Date());
u.setUpdated(new Date());
em.persist(u);
em.flush();
em.refresh(u);
return u;
}
}
#ManagedBean
#ViewScoped
public class UsersList implements Serializable {
private List<Users> uList;
private Users selUser ;
private Users user;
private String operation;
private #EJB UsersFacade ufs;
private FacesContext context;
private FacesMessage msg;
private Boolean edit=false;
public UsersList(){
ufs = new UsersFacade();
}
public void getAllUsersList(){
uList=ufs.findAll();
}
public Boolean isEdit() {
return edit;
}
public void add(){
context = FacesContext.getCurrentInstance();
operation = "new";
edit=true;
selUser = new Users();
}
public void save(){
context = FacesContext.getCurrentInstance();
if (operation.equals("new")){
ufs.create(selUser);
}
ufs.save(selUser);
operation = null;
msg = new FacesMessage(FacesMessage.SEVERITY_INFO,"Success", "Record Saved");
context.addMessage(null, msg);
edit=false;
getAllUsersList(); //refresh table
}
public void delete(Users u){
context = FacesContext.getCurrentInstance();
ufs.delete(u);
msg = new FacesMessage(FacesMessage.SEVERITY_INFO,"Success", "Record Deleted");
context.addMessage(null, msg);
}
public void refresh(){
context = FacesContext.getCurrentInstance();
getAllUsersList();
msg = new FacesMessage(FacesMessage.SEVERITY_INFO,"Success", "Data Refreshed");
context.addMessage(null, msg);
}
public List<Users> getuList() {
uList = ufs.findAll();
return uList;
}
public void setuList(List<Users> uList) {
this.uList = uList;
}
public Users getSelUser() {
return selUser;
}
public void setSelUser(Users selUser) {
this.selUser = selUser;
}
public void onRowSelect(SelectEvent event) {
edit=true;
context = FacesContext.getCurrentInstance();
msg = new FacesMessage("User Selected", ((Users) event.getObject()).getLogin_name());
context.addMessage(null, msg);
}
public void onRowUnSelect(UnselectEvent event) {
edit=false;
context = FacesContext.getCurrentInstance();
msg = new FacesMessage("User Unselected", ((Users) event.getObject()).getLogin_name());
context.addMessage(null, msg);
}
public Users getUser() {
return user;
}
}
below is user.xhtml
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<body>
<ui:composition template="./../../WEB-INF/Templates/Template.xhtml">
<ui:define name="menu">
</ui:define>
<ui:define name="content">
<h:form id="form">
<p:growl id="growl" showDetail="true"/>
<p:dataTable id="utable" var="users"
value="#{usersList.getuList()}"
selection="#{usersList.selUser}"
rowKey="#{users.iduser}"
selectionMode="single"
paginator="true" rows="5"
paginatorPosition="bottom"
editable="true"
>
<p:ajax event="rowSelect" listener="#{usersList.onRowSelect}" update=":form:display :form:growl" />
<p:ajax event="rowUnselect" listener="#{usersList.onRowUnSelect}" update=":form:growl"/>
<f:facet name="header">
List of Users
</f:facet>
<p:column id="login" sortBy ="#{users.login_name}">
<f:facet name="header">Login</f:facet>
<h:outputText value="#{users.login_name}" />
</p:column>
<p:column id="fullname" sortBy ="#{users.fullName}">
<f:facet name="header">User Name</f:facet>
<h:outputText value="#{users.fullName}" />
</p:column>
<p:column id="email" sortBy ="#{users.email}">
<f:facet name="header">E-mail</f:facet>
<h:outputText value="#{users.email}" />
</p:column>
<p:column id="phone" sortBy ="#{users.phone}">
<f:facet name="header">Phone</f:facet>
<h:outputText value="#{users.phone}" />
</p:column>
<p:column id="created" sortBy ="#{users.created}">
<f:facet name="header">Created On</f:facet>
<h:outputText value="#{users.created}" />
</p:column>
<p:column id="active" sortBy ="#{users.active}">
<f:facet name="header">Active</f:facet>
<h:outputText value="#{users.active}" />
</p:column>
<p:column id="userType" sortBy ="#{users.userType}">
<f:facet name="header">User Type</f:facet>
<h:outputText value="#{users.userType}" />
</p:column >
</p:dataTable>
<p:panel header="Edit User Properties">
<h:panelGrid id="display" columns="6" cellpadding="4" >
<h:outputText value="Login:" />
<p:inputText readonly="#{usersList.edit}"
value="#{usersList[usersList.edit ? 'user' : 'selUser'].login_name}" />
<h:outputText value="Password:" />
<p:inputText readonly="#{usersList.edit}"
value="#{usersList[usersList.edit ? 'user' : 'selUser'].password}" />
<h:outputText value="User Name:" />
<p:inputText readonly="#{usersList.edit}"
value="#{usersList[usersList.edit ? 'user' : 'selUser'].fullName}" />
<h:outputText value="E-mail:" />
<p:inputText readonly="#{usersList.edit}"
value="#{usersList[usersList.edit ? 'user' : 'selUser'].email}" />
<h:outputText value="Phone:" />
<p:inputText readonly="#{usersList.edit}"
value="#{usersList[usersList.edit ? 'user' : 'selUser'].phone}" />
<h:outputText value="User Type:" />
<p:inputText readonly="#{usersList.edit}"
value="#{usersList[usersList.edit ? 'user' : 'selUser'].userType}" />
<h:outputText value="Active:" />
<p:selectBooleanCheckbox
value="#{usersList[usersList.edit ? 'user' : 'selUser'].active}"/>
</h:panelGrid>
<h:panelGrid id="command" columns="6" cellpadding="4" >
<p:commandButton id="new" value="New" actionListener="#{usersList.add()}"
update="result,utable,display"
rendered="#{usersList.edit}}">
</p:commandButton>
<p:commandButton id="save" value="Save" actionListener="#{usersList.save()}" update="result utable">
</p:commandButton>
<p:commandButton id="delete" value="Delete" actionListener="#{usersList.delete()}" update="result utable">
</p:commandButton>
<p:commandButton id="refresh" value="Refresh" actionListener="#{usersList.refresh()}" update="result utable">
</p:commandButton>
</h:panelGrid>
<p:messages id="result" showDetail="true" autoUpdate="true"/>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</body>
</html>

Related

operations on validated text fields in jsf

I'm Using Primefaces 3.5. I have around 10 input text fields in my .xhtml page.Few text fields are made mandatory with attribute required="true".
I have a search button that displays Data from Database in a Data Table.The functionality of my page is to insert the values into these fields by on row select() the data in the Data Table of Search Button.
The Problem here is the data is inserting into the Fields which are highlighted with the red border ie fields with validations applied.
Example:
Transport Field has no validation but it had value that has to be inserted. These type of things are happening to many of my Input Fields.
Please give me some suggestions.
.xhtml file is:
<p:inputText id="email" value="#{addcust.c.email}" required="true"
validatorMessage="Enter Valid Email">
<f:validateRegex pattern="^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*#[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$"/></p:inputText>
<h:outputLabel value="Transport"></h:outputLabel>
<p:inputText value="#{addcust.c.transport}" </p:inputText>
<p:commandButton value="add" type="submit" update=":form,:msg" actionListener="#{addcust.onAddSelect}"</p:commandButton>
<p:commandButton value="Search" type="submit" onclick="ser.show() "></p:commandButton>
<p:dialog id="dialog11" header=" Search" widgetVar="ser" resizable="false" showEffect="fade"
hideEffect="explode" >
<p:dataTable id="dt" var="sd" value="#{addcust.al}" selection="#{addcust.c}">
<p:ajax event="rowSelect" update=":form" listener="#{addcust.onRowSelect}"
oncomplete="ser.hide()"/>
<p:column>
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{sd.email}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Transport"/>
</f:facet>
<h:outputText value="#{sd.transport}"/>
</p:column>
</p:dataTable>
customerbean.java
public class customerbean {
private String email;
private String transport;
public String getTransport() {
return transport;
}
public void setTransport(String transport) {
this.transport = transport;
}
return email;
}
public void setEmail(String email) {
this.email = email;
}
addcust.java
public customerbean c = new customerbean();
public ArrayList<customerbean> al;
public void onAddSelect(){
// Inserted my values into customer table.
}
public void onSearchSelect() {
try {
st = con.createStatement();
ResultSet rs = st.executeQuery("select * from customer where cmpid=" + getCurrcompanyid() + "");
al = new ArrayList<customerbean>();
while (rs.next()) {
customerbean s = new customerbean();
s.setEmail(rs.getString(1));
s.setTransport(rs.getString(2));
}
} catch (Exception e) {
System.out.println(e);
}
}
public void onRowSelect(SelectEvent event) throws SQLException {
customerbean r = (customerbean)event.getObject();
c = r;
}
If I'm not clear enough please leave me a comment .Thanks for Reading.

Not getting value on selection of row using prime faces

i am having problem on getting the value on selection of row under the table field using prime faces.
Requirement is that as i select row the associated data and relevant information must be shown on same page here like i want to show only gender and address of particular user under the table .
I am using jsf 2.0 and prime faces 3.5
here is my code please check it where i have mistaking
package com.poc.faces;
all imports
.............
..............
#ManagedBean
#SessionScoped
public class UserManagedBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public static List<User> list = new ArrayList<User>();
static {
list.add(new User(3, "ankurjadiya", "jadiyaankur#gmail.com",
"88849113", new Date(), "M", "sare ga ma pa"));
list.add(new User(1, "Administrator", "admin#gmail.com", "9000510456",
new Date(), "M", "Hyderabad"));
list.add(new User(2, "Guest", "guest#gmail.com", "9247469543",
new Date(), "M", "Hyderabad"));
list.add(new User(3, "John", "John#gmail.com", "9000510456",
new Date(), "M", "Hyderabad"));
list.add(new User(4, "Paul", "Paul#gmail.com", "9247469543",
new Date(), "M", "Hyderabad"));
list.add(new User(5, "raju", "raju#gmail.com", "9000510456",
new Date(), "M", "Hyderabad"));
}
private String username;
private String password;
private String searchUser;
private User selectedUser;
private UserDataModel dataModel;
public UserManagedBean() {
this.dataModel = new UserDataModel(list);
}
setter and getter of fields
..............
...............
public String login() {
if ("ankur".equalsIgnoreCase(getUsername())
&& "ankur".equals(getPassword())) {
return "home";
} else {
FacesContext context = FacesContext.getCurrentInstance();
context.addMessage("username", new FacesMessage(
"Invalid UserName and Password"));
return "login";
}
}
User data model class
public class UserDataModel extends ListDataModel<User> implements Serializable,
SelectableDataModel<User> {
public UserDataModel() {
}
public UserDataModel(List<User> users) {
super(users);
}
public User getRowData(String username) {
List<User> list = (List<User>) getWrappedData();
for (User user : list) {
if (user.getUsername().equals(username))
return user;
}
return null;
}
public Object getRowKey(User user) {
// TODO Auto-generated method stub
return user.getUsername();
}
}
public void onRowSelect(SelectEvent event) {
FacesMessage msg = new FacesMessage("User Selected",
((User) event.getObject()).getUsername());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onRowUnselect(UnselectEvent event) {
FacesMessage msg = new FacesMessage("User Unselected",
((User) event.getObject()).getUsername());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
This is home.xtml where i retrieving the value
<html xmlns="http://www.w3c.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"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<link href="../css/style.css" type="text/css" rel="stylesheet" />
</h:head>
<h:body>
<h:form prependId="false" id="form">
<p:layout style="min-width:400px;min-height:200px;" id="layout"
fullPage="true">
<p:layoutUnit position="west" header="Menu" collapsible="true">
<p:menu>
<p:submenu label="Resources">
<p:menuitem value="Option1"
action="#{userManagedBean.getSearchUsersResults()}"
update="left_column" />
</p:submenu>
</p:menu>
</p:layoutUnit>
<p:layoutUnit position="center">
<p:panel id="left_column"
style="width: 2px; left: 2px; margin-left: 2px">
<center>
<H1>UserData</H1>
<br />
<p:dataTable value="#{userManagedBean.dataModel}" var="user"
pagination="true" rows="5" selection="#{userManagedBean.selectedUser}" selectionMode="single" >
<p:column>
<f:facet name="header">UserId</f:facet>
<h:outputText value="#{user.userId}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">Username</f:facet>
<h:outputText value="#{user.username}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">EmailId</f:facet>
<h:outputText value=" #{user.emailId}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">Phone</f:facet>
<h:outputText value="#{user.phone}"></h:outputText>
</p:column>
</p:dataTable>
</center>
</p:panel>
<h:panelGrid id="display" columns="2" cellpadding="4">
<h:outputText value="Gender:" />
<h:inputText value="#{userManagedBean.selectedUser.gender}" />
<h:outputText value="Address:" />
<h:inputText value="#{userManagedBean.selectedUser.address}" />
</h:panelGrid>
` </p:layoutUnit>
<p:layoutUnit position="south" footer="bottom">
</p:layoutUnit>
</p:layout>
</h:form>
</h:body>
</html>
You need to set the rowKey attribute on the <p:dataTable/> to properly enable row selection. The rowKey attribute should be set to a unique identifier for the entity in your datatable, like the primary key attribute. From your sample, it'll look something like:
<p:dataTable value="#{userManagedBean.dataModel}" rowKey="#{user.userId}" var="user" pagination="true" rows="5" selection="#{userManagedBean.selectedUser}" selectionMode="single">

NumberFormatException for input String in datatable

I have the following method in my DAO where I retrieve a list of persons :
public List<Personne> getAllUsers() {
Query query = em.createQuery("SELECT p FROM Personne p where TYPE(p) =Utilisateur");
#SuppressWarnings("unchecked")
List <Personne> personnes = query.getResultList();
return personnes;
}
I want to show the list of persons in a datatable :
<p:dataTable value="#{desacBean.users}" var="us" paginator="true" selection="# {desacBean.selectedUser}" selectionMode="single" rowKey="#{desacBean.getId(us)}}" first="1">
<p:ajax event="rowSelect" listener="#{desacBean.onUserSelect}"/>
<p:column>
<f:facet name="n">
<h:outputText value="nom" />
</f:facet>
<h:outputText value="#{us.nom}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="prenom" />
</f:facet>
<h:outputText value="#{us.prenom}"/>
</p:column>
</p:dataTable>
my BEAN :
#ManagedBean(name="desacBean")
#SessionScoped
public class DesactiveBean implements Serializable{
private static final long serialVersionUID = 1L;
private List<Personne> users = new ArrayList<Personne>();
private Personne selectedUser;
private boolean panelRendered;
UserDAO daoUser = new UserDaoImpl();
public void rowSelect(SelectEvent event){
selectedUser = (Personne)event.getObject();
System.out.println("selectedUser = "+selectedUser.getNom_ut());
this.panelRendered = true;
}
public int getId(Personne car)
{
return System.identityHashCode(car);
}
public void onUserSelect(SelectEvent event){
this.selectedUser = (Personne)event.getObject();
System.out.println("selectedUser = "+selectedUser.getNom_ut());
}
I have the following error when trying to show this dataTable :
java.lang.NumberFormatException: For input string: "prenom"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.parseInt(Integer.java:527)
For input string: "prenom"
how can I fix it?
You'll probably encountering the same issue as the question answered here: NumberFormatException for input String

Primefaces Collector Remove not working

I am testing the primefaces collector example given in Showcase for my code
I read somewhere that its necessary to override the equals and hashcode method for that.
Even after overriding the methods , I am still getting the same error.
Kindly tell me whats wrong in my code
User.java
#ManagedBean
public class User implements Serializable{
public String name;
public String designation;
public String division;
public User(String name,String division){
setName(name);
setDivision(division);
}
public User(){
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public String getDivision() {
return division;
}
public void setDivision(String userDivision) {
this.division = userDivision;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
commApprover.java
#ManagedBean
#ViewScoped
public class CommApprover implements Serializable{
private User approver = new User();
private List<User> approvers = new ArrayList<User>();
public String reinit() {
approver = new User();
return null;
}
public User getApprover() {
return approver;
}
public void setApprover(User approver) {
this.approver = approver;
}
public List<User> getApprovers() {
return approvers;
}
public void setApprovers(List<User> approvers) {
this.approvers = approvers;
}
#Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
if (approver!= null ? !approver.equals(this.approver) : this.approver != null)
return false;
return true;
}
#Override
public int hashCode()
{
int result = approver.hashCode();
return result;
}
}
index.xhtml
<p:growl id="msgs" />
<p:panel header="Approval Route ">
<h:panelGrid columns="3" id="grid">
<h:outputText value="Name*" />
<h:outputText value="Designation*" />
<h:outputText value="Division*" />
<p:inputText id="app_name" value="#{commApprover.approver.name}" required="true"/>
<p:inputText id="app_designation" value="#{commApprover.approver.designation}" required="true"/>
<p:inputText id="app_division" required="true" value="# {commApprover.approver.division}" />
<p:commandButton id="btn_add" value="Add" update="approvers #parent" action="#{commApprover.reinit}" >
<p:collector value="#{commApprover.approver}" addTo="#{commApprover.approvers}" />
</p:commandButton>
</h:panelGrid>
</p:panel>
<p:outputPanel id="approvers">
<p:dataTable id="approversTable" value="#{commApprover.approvers}" var="approver">
<p:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{approver.name}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Designation" />
</f:facet>
<h:outputText value="#{approver.designation}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Division" />
</f:facet>
<h:outputText value="#{approver.division}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Operation" />
</f:facet>
<p:commandLink ajax="true" value="Remove" update=":appform:approvers" process=":appform:approvers">
<p:collector value="#{approver}" removeFrom="#{commApprover.approvers}" />
</p:commandLink>
</p:column>
</p:dataTable>
</p:outputPanel>
</h:form>
This post is old but I ran into the same problem and after some debuging I found out that this problem is related to incorrectly implemented hashCode and equals, when using converters or p:collector you have to implement hashCode and equals to compare all fields in your entity otherwise it fails even if the item you are trying to remove is the correct one. Also it is recomended that you override those properties in your Pojo not in you ManagedBean. This post helped me to understand the problem https://blog.art-of-coding.eu/jsf-converters-and-equals-hashcode/

Request parameter is null during postback

I have a view that display a list of users, from this view I can go to another view of "details" of any selected user. In the details view I need to select some values from 2 select list and then in the backed bean take these values, and add them to an user to finally store (update) the user in the database. These are my methods in the "user Bean".
With this method I get the user id from the "list of users view" and retrieve the user from the database to display its info on the details view.
public void getParam(){
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
//Obtener parametros del request
Map<String, String> parameterMap = (Map<String, String>) externalContext.getRequestParameterMap();
Long param = Long.valueOf(parameterMap.get("id_usuario"));
System.out.println(param);
this.setU(controlador.getUser(param));
}
With this method I set the values from the select list to an object and then I add this object to the user, finally I save it on the database.
public void setPrivilegio(){
System.out.println("hola");
Privilegio pri=new Privilegio();
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
//Obtener parametros del request
Map parameterMap = externalContext.getRequestParameterMap();
Agrupacion agrupacion= (Agrupacion)parameterMap.get("agrup");
System.out.println(agrupacion.getNombre());
Rol rol = (Rol)parameterMap.get("rols");
System.out.println(rol.getNombre());
System.out.println(""+rol.getNombre()+" "+agrupacion.getNombre());
pri.setRol(rol);
pri.setAgrupacion(agrupacion);
pri.setActive(true);
this.getU().addPrivilegio(pri);
controlador.saveUsuario(this.getU());
}
This is my view:
<?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">
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<div class="container">
<h:panelGroup id="Usuarios">
<h:form id="FormUsuarios">
<h2>Detalles Usuario</h2>
<h:dataTable id="users" value="#{usuario.u}" styleClass="table table-striped table-bordered" headerClass="sorting_asc"
rowClasses="odd,even">
<h:column>
<f:facet name="header">#</f:facet>
#{usuario.u.id}
</h:column>
<h:column>
<f:facet name="header">Identificador</f:facet>
<h:inputText id="identificador" value="#{usuario.u.identificador}" />
</h:column>
<h:column>
<f:facet name="header">Nombre</f:facet>
<h:inputText id="nombres" value=" #{usuario.u.nombres}"/> <h:inputText id="apellidoP" value=" #{usuario.u.apellidoPaterno}"/> <h:inputText id="apellidoM" value=" #{usuario.u.apellidoMaterno}"/>
</h:column>
<h:column>
<f:facet name="header">Active</f:facet>
<h:selectBooleanCheckbox id="check" value="#{usuario.u.active}"></h:selectBooleanCheckbox>
</h:column>
</h:dataTable>
<h3>Asignar Privilegios</h3>
<h:selectOneMenu id="agrup" value="#{usuario.selected}" converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{agrupacion.agrupacion}" var="entity" itemLabel="#{entity.nombre}" itemValue="#{entity.id}"/>
</h:selectOneMenu>
<h:selectOneMenu id="rols" value="#{rol.selected}" converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{rol.roles}" var="rol" itemLabel="#{rol.nombre}" itemValue="#{rol.id}"/>
</h:selectOneMenu>
<h:commandButton value="Asignar" styleClass="btn-primary" actionListener="#{usuario.setPrivilegio}">
</h:commandButton>
<h3>Privilegios Asignados:</h3>
<h:dataTable id="privilegios" value="#{usuario.u.privilegios}" var="p" styleClass="table table-striped table-bordered" headerClass="sorting_asc"
rowClasses="odd,even">
<h:column>
<f:facet name="header">#</f:facet>
#{p.id}
</h:column>
<h:column>
<f:facet name="header">Roles</f:facet>
#{p.rol.nombre}
</h:column>
<h:column>
<f:facet name="header">Grupos</f:facet>
#{p.agrupacion.nombre}
</h:column>
<h:column>
<f:facet name="header">Active</f:facet>
<h:selectBooleanCheckbox id="checkbox" value="#{p.active}"></h:selectBooleanCheckbox>
</h:column>
</h:dataTable>
</h:form>
<script type="text/javascript" src="js/paging-bootstrap.js"></script>
<script type="text/javascript" src="js/contenidoc.datatable.init.js"></script>
</h:panelGroup>
</div>
</ui:composition>
When I click on my commandbutton called "Asignar" that calls the method setPrivilegio(), I get this error:
java.lang.NumberFormatException: null
at java.lang.Long.parseLong(Long.java:404)
at java.lang.Long.valueOf(Long.java:540)
at cl.uchile.sti.bean.UsuarioBean.getParam(UsuarioBean.java:114)
The tables in the view shows all the info, but when I want to call the method that add the selected items to the user and save it on the database (setPrivilegio) I get this error.
How is this caused and how can I solve it?
This is my full "user bean":
#ManagedBean(name = "usuario")
#ViewScoped
public class UsuarioBean {
private usuarioController controlador;
private Usuario u=new Usuario();
private Privilegio Selected=new Privilegio();
private Boolean active;
private long id_user;
#PostConstruct
public void init() {
controlador=new usuarioController();
}
public long getId_user() {
return id_user;
}
public void setId_user(long id_user) {
this.id_user = id_user;
}
public Privilegio getSelected() {
return Selected;
}
public void setSelected(Privilegio selected) {
Selected = selected;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public Usuario getU() {
getParam();
return u;
}
public void setU(Usuario u) {
this.u = u;
}
private List<Usuario> usuario;
public List<Usuario> getUsuario() {
usuario=UsuarioDAO.getAll();
return usuario;
}
public Usuario getById(long id_usuario){
return u;
}
public void setUsuario(List<Usuario> usuario) {
this.usuario = usuario;
}
public void saveUsuario(Usuario u){
controlador.saveUsuario(u);
}
public void getParam(){
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
//Obtener parametros del request
Map<String, String> parameterMap = (Map<String, String>) externalContext.getRequestParameterMap();
Long param = Long.valueOf(parameterMap.get("id_usuario"));
System.out.println(param);
this.setU(controlador.getUser(param));
}
public void setPrivilegio(){
System.out.println("hola");
Privilegio pri=new Privilegio();
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
//Obtener parametros del request
Map parameterMap = externalContext.getRequestParameterMap();
Agrupacion agrupacion= (Agrupacion)parameterMap.get("agrup");
System.out.println(agrupacion.getNombre());
Rol rol = (Rol)parameterMap.get("rols");
System.out.println(rol.getNombre());
System.out.println(""+rol.getNombre()+" "+agrupacion.getNombre());
pri.setRol(rol);
pri.setAgrupacion(agrupacion);
pri.setActive(true);
this.getU().addPrivilegio(pri);
controlador.saveUsuario(this.getU());
}
}
this is the first view (list of users, from which i go to user details)
<?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">
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<div class="container">
<h:panelGroup id="Usuarios">
<h:form id="FormUsuarios">
<h2>Listado de Usuarios</h2>
<h:graphicImage url="http://a.dryicons.com/images/icon_sets/simplistica/png/128x128/add.png" width="30" height="30"/>
<h:dataTable id="users" value="#{usuario.usuario}" var="o" styleClass="table table-striped table-bordered" headerClass="sorting_asc"
rowClasses="odd,even">
<h:column>
<f:facet name="header">#</f:facet>
#{o.id}
</h:column>
<h:column>
<f:facet name="header">Identificador</f:facet>
#{o.identificador}
</h:column>
<h:column>
<f:facet name="header">Nombre</f:facet>
#{o.nombres} #{o.apellidoMaterno} #{o.apellidoPaterno}
</h:column>
<h:column>
<f:facet name="header">Active</f:facet>
<h:selectBooleanCheckbox id="check" value="#{o.active}"></h:selectBooleanCheckbox>
</h:column>
<h:column>
<f:facet name="header">Detalles</f:facet>
<h:outputLink value="contenido/detalleUsuario.xhtml">
Detalle
<f:param name="id_usuario" value="#{o.id}" />
</h:outputLink>
</h:column>
</h:dataTable>
</h:form>
<script type="text/javascript" src="js/paging-bootstrap.js"></script>
<script type="text/javascript" src="js/contenidoc.datatable.init.js"></script>
</h:panelGroup>
</div>
</ui:composition>
Bad getter!
public Usuario getU() {
getParam();
return u;
}
The getter above is a very bad idea. You've said it yourself that the variable makes it into the usuario backing bean(this I doubt). It is just plain wrong to perform business logic inside a getter because of inconsistencies (like you're experiencing) and the fact that the getter is called multiple times during a request. There are more elegant and cleaner ways to pass and initialise parameters between JSF pages.
private Usuario u=new Usuario(); is also a bad idea. Why is this necessary when you have
this.setU(controlador.getUser(param));
All that should happen inside your #PostConstructor
#PostConstruct
public void init() {
controlador=new usuarioController();
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
//Obtener parametros del request
Map<String, String> parameterMap = (Map<String, String>) externalContext.getRequestParameterMap();
Long param = Long.valueOf(parameterMap.get("id_usuario"));
System.out.println(param);
this.setU(controlador.getUser(param));
}
The getter should just be plain
public Usuario getU() {
return u;
}
The cause of this error is that parameterMap.get("id_usuario") is null. You should investigate how you pass this parameter from the UI to the backing bean.

Resources