How to refresh ViewScoped(Omnifaces) page on data change? - jsf

I have some Category model, that is organized as adjacency list. So when i am adding new one, i format current list so it has viewable hierarchy. For this i use Omnifaces ViewScoped bean. Upon loading data i format it and display it in selectOneMenu. When i add new category that has parent to it i redirect to category list. If i open form page again it doesn't display new hierarchy but puts new category on the end as if it doesn't have parent. If i restart server for example and load page again it is displayed as it should.
So my question is how do i refresh it properly since obviouslu i am not doing it right.
form.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
template="#{adminConfig.templatePath}"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:define name="title">#{categoryFormMB.title}</ui:define>
<ui:define name="description"></ui:define>
<ui:define name="body">
<f:metadata>
<f:viewParam name="id" value="#{categoryFormMB.id}" converter="javax.faces.Long"/>
<f:event type="preRenderView" listener="#{categoryFormMB.initForm()}"/>
</f:metadata>
<div class="row">
<div class="col-md-6">
<p:panel styleClass="box box-primary">
<h:form styleClass="form-horizontal">
<div class="form-group ui-flat">
<p:outputLabel
for="name"
value="#{label.categoryName}"
styleClass="control-label col-md-4"/>
<div class="col-md-8">
<p:inputText
id="name"
value="#{categoryFormMB.category.name}"
styleClass="form-control"
required="true" />
</div>
</div>
<div class="form-group ui-flat">
<p:outputLabel
for="slug"
value="#{label.categorySlug}"
styleClass="control-label col-md-4"/>
<div class="col-md-8">
<p:inputText
id="slug"
value="#{categoryFormMB.category.slug}"
styleClass="form-control"
required="true" />
</div>
</div>
<div class="form-group ui-flat">
<p:outputLabel
for="parent"
value="#{label.parentCategory}"
styleClass="control-label col-md-4"/>
<div class="col-md-8">
<p:selectOneMenu
value="#{categoryFormMB.category.parent}"
id="parent"
converter="categoryConv">
<f:selectItem
itemLabel="#{label.noParent}"
itemValue=""/>
<f:selectItems
value="#{categoryFormMB.formattedList}"
var="category"
itemValue="#{category}"
itemLabel="#{category.name}"/>
</p:selectOneMenu>
</div>
</div>
<div class="form-group ui-flat">
<p:outputLabel
for="description"
value="#{label.categoryDescription}"
styleClass="control-label col-md-4"/>
<div class="col-md-8">
<p:inputTextarea
id="description"
value="#{categoryFormMB.category.description}"
styleClass="form-control"/>
</div>
</div>
<div class="form-group ui-flat">
<p:outputLabel
for="title-tag"
value="#{label.titleTag}"
styleClass="control-label col-md-4"/>
<div class="col-md-8">
<p:inputText
id="title-tag"
value="#{categoryFormMB.category.titleTag}"
styleClass="form-control"/>
</div>
</div>
<div class="form-group ui-flat">
<p:outputLabel
for="description-tag"
value="#{label.descriptionTag}"
styleClass="control-label col-md-4"/>
<div class="col-md-8">
<p:inputTextarea
id="description-tag"
value="#{categoryFormMB.category.descriptionTag}"
styleClass="form-control"/>
</div>
</div>
<div class="form-group">
<div class="col-md-4"></div>
<div class="col-md-8">
<div class="pull-right">
<p:commandButton
value="#{label.saveCategory}"
ajax="false"
rendered="#{ ! categoryFormMB.editing}"
action="#{categoryFormMB.save()}"
styleClass="btn btn-success btn-flat"
icon="fa fa-floppy-o"/>
<p:commandButton
value="#{label.updateCategory}"
ajax="false"
rendered="#{categoryFormMB.editing}"
action="#{categoryFormMB.update()}"
styleClass="btn btn-success btn-flat"
icon="fa fa-floppy-o"/>
<p:commandButton
value="#{label.cancel}"
action="#{categoryFormMB.close()}"
styleClass="btn btn-danger btn-flat"
ajax="false"
icon="fa fa-times"
immediate="true"/>
</div>
</div>
</div>
</h:form>
<p:messages
globalOnly="false"
showDetail="true"
showSummary="false"
showIcon="true" />
</p:panel>
</div>
</div>
</ui:define>
</ui:composition>
CategoryFormMB
package com.github.cvetan.bookstore.mb.category;
import static com.github.adminfaces.template.util.Assert.has;
import com.github.cvetan.bookstore.model.Category;
import com.github.cvetan.bookstore.sb.category.CategorySBLocal;
import com.github.cvetan.bookstore.util.Redirector;
import com.github.cvetan.bookstore.util.StringRepeater;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* #author cvetan
*/
#Named(value = "categoryFormMB")
#RequestScoped
public class CategoryFormMB {
#EJB
private CategorySBLocal categorySB;
private List<Category> list;
private List<Category> formattedList;
private String title;
private Integer id;
private boolean editing;
private Category category;
private String message;
/**
* Creates a new instance of CategoryFormMB
*/
public CategoryFormMB() {
}
public CategorySBLocal getCategorySB() {
return categorySB;
}
public void setCategorySB(CategorySBLocal categorySB) {
this.categorySB = categorySB;
}
public List<Category> getList() {
return list;
}
public void setList(List<Category> list) {
this.list = list;
}
public List<Category> getFormattedList() {
return formattedList;
}
public void setFormattedList(List<Category> formattedList) {
this.formattedList = formattedList;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public boolean isEditing() {
return editing;
}
public void setEditing(boolean editing) {
this.editing = editing;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void initForm() {
formattedList = new ArrayList<>();
getListFromDB();
formatList(list, 0);
if (has(id)) {
// TODO
} else {
title = "New category";
editing = false;
category = new Category();
message = "Category has been saved.";
}
}
private void getListFromDB() {
list = categorySB.getAll();
}
private void formatList(List<Category> list, int level) {
for (Category c: list) {
if (formattedList.contains(c)) {
continue;
}
c.setName(StringRepeater.repeat(" - ", level) + c.getName());
formattedList.add(c);
if ( ! c.getChildCategories().isEmpty()) {
formatList(c.getChildCategories(), level + 1);
}
}
}
public String save() {
try {
categorySB.save(category);
return Redirector.redirectWithInfo("Category has been saved.", "/admin/category-list.xhmtl?faces-redirect=true");
} catch (Exception ex) {
return Redirector.redirectWithError(ex.getMessage(), "/admin/category-form.xhtml?faces-redirect=true");
}
}
}
CategorySB(EJB)
package com.github.cvetan.bookstore.sb.category;
import com.github.cvetan.bookstore.model.Category;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
/**
*
* #author cvetan
*/
#Stateless
public class CategorySB implements CategorySBLocal {
#PersistenceContext (unitName = "BookstorePU")
private EntityManager entityManager;
#Override
public List<Category> getAll() {
return entityManager.createNamedQuery("Category.findAll").getResultList();
}
#Override
public void save(Category category) {
entityManager.persist(category);
}
#Override
public Category getById(int id) {
Query query = entityManager.createNamedQuery("Category.findById");
query.setParameter("id", id);
Category category = (Category) query.getSingleResult();
return category;
}
#Override
public void update(Category category) {
}
#Override
public void delete(int id) {
Category category = entityManager.find(Category.class, id);
entityManager.remove(category);
}
}
Category entity
package com.github.cvetan.bookstore.model;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* #author cvetan
*/
#Entity
#Table(name = "categories")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Category.findAll", query = "SELECT c FROM Category c")
, #NamedQuery(name = "Category.findById", query = "SELECT c FROM Category c WHERE c.id = :id")
, #NamedQuery(name = "Category.findByName", query = "SELECT c FROM Category c WHERE c.name = :name")
, #NamedQuery(name = "Category.findBySlug", query = "SELECT c FROM Category c WHERE c.slug = :slug")
, #NamedQuery(name = "Category.findByDescription", query = "SELECT c FROM Category c WHERE c.description = :description")
, #NamedQuery(name = "Category.findByTitleTag", query = "SELECT c FROM Category c WHERE c.titleTag = :titleTag")
, #NamedQuery(name = "Category.findByDescriptionTag", query = "SELECT c FROM Category c WHERE c.descriptionTag = :descriptionTag")
, #NamedQuery(name = "Category.findByCreatedAt", query = "SELECT c FROM Category c WHERE c.createdAt = :createdAt")
, #NamedQuery(name = "Category.findByUpdatedAt", query = "SELECT c FROM Category c WHERE c.updatedAt = :updatedAt")})
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "name")
private String name;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 255)
#Column(name = "slug")
private String slug;
#Size(max = 255)
#Column(name = "description")
private String description;
#Size(max = 255)
#Column(name = "title_tag")
private String titleTag;
#Size(max = 255)
#Column(name = "description_tag")
private String descriptionTag;
#Basic(optional = false)
#NotNull
#Column(name = "created_at")
#Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
#Column(name = "updated_at")
#Temporal(TemporalType.TIMESTAMP)
private Date updatedAt;
#OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private List<Category> childCategories;
#JoinColumn(name = "parent", referencedColumnName = "id")
#ManyToOne
private Category parent;
public Category() {
}
public Category(Integer id) {
this.id = id;
}
public Category(Integer id, String name, String slug, Date createdAt) {
this.id = id;
this.name = name;
this.slug = slug;
this.createdAt = createdAt;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitleTag() {
return titleTag;
}
public void setTitleTag(String titleTag) {
this.titleTag = titleTag;
}
public String getDescriptionTag() {
return descriptionTag;
}
public void setDescriptionTag(String descriptionTag) {
this.descriptionTag = descriptionTag;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
#XmlTransient
public List<Category> getChildCategories() {
return childCategories;
}
public void setChildCategories(List<Category> childCategories) {
this.childCategories = childCategories;
}
public Category getParent() {
return parent;
}
public void setParent(Category parent) {
this.parent = parent;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
if (!(object instanceof Category)) {
return false;
}
Category other = (Category) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return name;
}
#PrePersist
public void setCreatedAt() {
createdAt = new Date();
}
#PreUpdate
public void setUpdatedAt() {
updatedAt = new Date();
}
}

There is caching on the JPA/EclipseLink side, which i didn't know. When i clear cache with: entityManager.getEntityManagerFactory().getCache().evictAll(); it refreshes data. So problem was not on the bean or it's scope.

Related

How to change the default titles in p:galleria for all images to specific titles for each image

I implemented the example in PrimeFaces for the p:galleria. I can display my images and such with no problem. But I want each image to have it's own title. Here's my code:
<p:galleria value="#{mywork.images}" var="image" panelWidth="500" panelHeight="313"
showCaption="true" style="left:350px;">
<p:graphicImage name="/galleria/dotacion/#{image}" alt="Image Description for #{image}"
title="#{mywork.titles}" style="width:100%;"/>
</p:galleria>
and here is my bean:
package org.portfolio.util;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
#ManagedBean
public class Mywork {
private List<String> images;
private String titles = "";
private String titles2 = "";
#PostConstruct
public void init() {
images = new ArrayList<String>();
for (int i = 1; i <= 7; i++) {
images.add("pierrel"+i+".jpg");
if (i == 1) {
titles = "imagen de prueba if1";
getTitles();
}
if (i == 2){
titles = "imagen de prueba if2";
getTitles();
}
}
}
public List<String> getImages() {
return images;
}
public String getTitles() {
return titles;
}
public String getTitles2() {
return titles2;
}
}
What I am doing wrong or missing?
This is just returning me "imagen de prueba if2" for every image.
You can use an Object instead of using a list of string.
In you ManagedBean
#ManagedBean
public class Mywork {
private List<ImageObject> images;
#PostConstruct
public void init() {
images = new ArrayList<String>();
for (int i = 1; i <= 7; i++) {
images.add(new ImageObject("fileName" + i + ".jpg", "myDescription", "myTitle"));
}
}
public class ImageObject{
private String fileName;
private String description;
private String title;
public ImageObject(String fileName, String description, String title){
this.fileName = fileName;
this.description = description;
this.title = title;
}
//Getters setters
}
}
in your xhtml
<p:galleria value="#{mywork.images}" var="image" panelWidth="500" panelHeight="313" showCaption="true" style="left:350px;">
<p:graphicImage name="/galleria/dotacion/#{image.fileName}" alt="#{image.description}" title="#{image.title}" style="width:100%;"/>
</p:galleria>

p:columns inside ui:repeat is not working

I'm working on a project that requires a dataTable for each item of a collection, and each of those dataTables has dynamic columns.
Here's an example of what I want to do..
DocsDescriptor.java
package test;
public class DocsDescriptor {
private long id;
private String name;
public DocsDescriptor(long id, String name){
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
DocsData.java
package test;
public class DocsData {
private long id;
private String value;
private DocsDescriptor descriptor;
public DocsData(long id, String value, DocsDescriptor descriptor){
this.id = id;
this.value = value;
this.descriptor = descriptor;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public DocsDescriptor getDescriptor() {
return descriptor;
}
public void setDescriptor(DocsDescriptor descriptor) {
this.descriptor = descriptor;
}
}
DocsDocument.java
package test;
import java.util.ArrayList;
import java.util.List;
public class DocsDocument {
private long id;
private List<DocsData> datas;
public DocsDocument(long id){
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public List<DocsData> getDatas() {
return datas;
}
public void setDatas(List<DocsData> datas) {
this.datas = datas;
}
public void add(DocsData data){
if(this.datas == null) this.datas = new ArrayList<DocsData>();
this.datas.add(data);
}
}
DocsDocumentType.java
package test;
import java.util.ArrayList;
import java.util.List;
public class DocsDocumentType {
private long id;
private String name;
private List<DocsDocument> documents;
public DocsDocumentType(long id, String name){
this.id = id;
this.name = name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<DocsDocument> getDocuments() {
return documents;
}
public void setDocuments(List<DocsDocument> documents) {
this.documents = documents;
}
public void add(DocsDocument document){
if(this.documents == null) this.documents = new ArrayList<DocsDocument>();
this.documents.add(document);
}
}
TestController.java
package test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;
#ConversationScoped
#Named("test")
public class TestController implements Serializable{
private static final long serialVersionUID = 2433550537340132027L;
#Inject
protected Conversation conversation;
private List<DocsDocumentType> documentTypes;
public void start(){
if(this.conversation.isTransient())
this.conversation.begin();
if(this.conversation != null)
this.conversation.setTimeout(10800000);
}
#PostConstruct
public void init(){
DocsDescriptor dePhone = new DocsDescriptor(1,"Number");
DocsDescriptor deName = new DocsDescriptor(2,"Name");
DocsDescriptor deLastName = new DocsDescriptor(3,"Last Name");
DocsDescriptor dePrice = new DocsDescriptor(4,"Product Price");
DocsDescriptor deCode = new DocsDescriptor(5,"Product Code");
DocsDescriptor deProdName = new DocsDescriptor(6,"Product Name");
DocsDocument jl = new DocsDocument(1);
jl.add(new DocsData(1,"514237797", dePhone));
jl.add(new DocsData(2,"John", deName));
jl.add(new DocsData(3,"Lennon", deLastName));
DocsDocument pm = new DocsDocument(2);
pm.add(new DocsData(4,"45312342", dePhone));
pm.add(new DocsData(5,"Paul", deName));
pm.add(new DocsData(6,"McCartney", deLastName));
DocsDocument rs = new DocsDocument(3);
rs.add(new DocsData(7,"567523534", dePhone));
rs.add(new DocsData(8,"Richard", deName));
rs.add(new DocsData(9,"Starkey", deLastName));
DocsDocument gh = new DocsDocument(3);
gh.add(new DocsData(10,"454623243", dePhone));
gh.add(new DocsData(11,"George", deName));
gh.add(new DocsData(12,"Harrison", deLastName));
DocsDocumentType identity = new DocsDocumentType(1,"Beatles");
identity.add(jl);
identity.add(pm);
identity.add(gh);
identity.add(rs);
DocsDocument iPhone = new DocsDocument(4);
iPhone.add( new DocsData(13,"iPhone 6S",deProdName));
iPhone.add( new DocsData(15,"23452340",deCode));
iPhone.add( new DocsData(16,"$650",dePrice));
DocsDocument nexus = new DocsDocument(5);
nexus.add( new DocsData(13,"Nexus 6P",deProdName));
nexus.add( new DocsData(15,"786338675",deCode));
nexus.add( new DocsData(16,"$600",dePrice));
DocsDocumentType product = new DocsDocumentType(1,"Product");
product.add(iPhone);
product.add(nexus);
this.documentTypes = new ArrayList<DocsDocumentType>();
this.documentTypes.add(identity);
this.documentTypes.add(product);
}
public List<DocsDocumentType> getDocumentTypes() {
return documentTypes;
}
public void setDocumentTypes(List<DocsDocumentType> documentTypes) {
this.documentTypes = documentTypes;
}
}
test.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>TEST</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</h:head>
<h:body>
<f:event type="preRenderView" listener="#{test.start}"/>
<h:panelGroup id="bigArea" style="width : 100%">
<ui:repeat value="#{test.documentTypes}" var="dt">
<p:panelGrid style="width : 750px">
<f:facet name="header">
<p:row>
<p:column style="width : 750px; text-align: left"><h:outputText value="#{dt.name}" /></p:column>
</p:row>
</f:facet>
<p:row>
<p:column>
<p:dataTable value="#{dt.documents}" var="doc" emptyMessage="...">
<p:columns value="#{doc.datas}" var="data">
<f:facet name="header"><h:outputText value="#{data.descriptor.name}"/></f:facet>
<h:outputText value="#{data.value}" />
</p:columns>
</p:dataTable>
</p:column>
</p:row>
</p:panelGrid>
</ui:repeat>
</h:panelGroup>
</h:body>
</html>
And here's the output:
http://picpaste.com/Captura_de_pantalla_2015-12-12_a_las_19.11.27_1-0Fd7lEtY.png
I'm using wildfly 9.0.1, primefaces-5.2
Can anybody help me out with a solution or an alternative?
Thank you all!
Value of p:columns cannot refer to var of parent dataTable. Documentation http://www.primefaces.org/showcase/ui/data/datatable/columns.xhtml shows this moment. Actually in your model each row can contain different number of columns. You need to change model:
TableModel:
package test;
import java.util.ArrayList;
import java.util.List;
/**
* Created by kit on 14.12.2015.
*
* #author kit
*/
public class TableModel {
private String name;
private List<RowModel> rows = new ArrayList<>();
private List<ColumnModel> columns = new ArrayList<>();
/**
* Getters, Setters
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<RowModel> getRows() {
return rows;
}
public List<ColumnModel> getColumns() {
return columns;
}
}
RowModel:
package test;
import java.util.HashMap;
import java.util.Map;
/**
* Created by kit on 14.12.2015.
*
* #author kit
*/
public class RowModel<T> {
private String name;
private Map<ColumnModel, T> data = new HashMap<>();
/**
* Getters, Setters
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Map<ColumnModel, T> getData() {
return data;
}
}
ColumnModel:
package test;
/**
* Created by kit on 14.12.2015.
*
* #author kit
*/
public class ColumnModel<T> {
private T data;
/**
* Getters, Setters
*/
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
Modify TestController:
package test;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
#ConversationScoped
#Named("test")
public class TestController implements Serializable {
private static final long serialVersionUID = 2433550537340132027L;
#Inject
protected Conversation conversation;
private List<TableModel> tables = new ArrayList<>();
private List<DocsDocumentType> documentTypes;
public void start() {
if (this.conversation.isTransient())
this.conversation.begin();
if (this.conversation != null)
this.conversation.setTimeout(10800000);
}
#PostConstruct
public void init() {
DocsDescriptor dePhone = new DocsDescriptor(1, "Number");
DocsDescriptor deName = new DocsDescriptor(2, "Name");
DocsDescriptor deLastName = new DocsDescriptor(3, "Last Name");
DocsDescriptor dePrice = new DocsDescriptor(4, "Product Price");
DocsDescriptor deCode = new DocsDescriptor(5, "Product Code");
DocsDescriptor deProdName = new DocsDescriptor(6, "Product Name");
DocsDocument jl = new DocsDocument(1);
jl.add(new DocsData(1, "514237797", dePhone));
jl.add(new DocsData(2, "John", deName));
jl.add(new DocsData(3, "Lennon", deLastName));
DocsDocument pm = new DocsDocument(2);
pm.add(new DocsData(4, "45312342", dePhone));
pm.add(new DocsData(5, "Paul", deName));
pm.add(new DocsData(6, "McCartney", deLastName));
DocsDocument rs = new DocsDocument(3);
rs.add(new DocsData(7, "567523534", dePhone));
rs.add(new DocsData(8, "Richard", deName));
rs.add(new DocsData(9, "Starkey", deLastName));
DocsDocument gh = new DocsDocument(3);
gh.add(new DocsData(10, "454623243", dePhone));
gh.add(new DocsData(11, "George", deName));
gh.add(new DocsData(12, "Harrison", deLastName));
DocsDocumentType identity = new DocsDocumentType(1, "Beatles");
identity.add(jl);
identity.add(pm);
identity.add(gh);
identity.add(rs);
DocsDocument iPhone = new DocsDocument(4);
iPhone.add(new DocsData(13, "iPhone 6S", deProdName));
iPhone.add(new DocsData(15, "23452340", deCode));
iPhone.add(new DocsData(16, "$650", dePrice));
DocsDocument nexus = new DocsDocument(5);
nexus.add(new DocsData(13, "Nexus 6P", deProdName));
nexus.add(new DocsData(15, "786338675", deCode));
nexus.add(new DocsData(16, "$600", dePrice));
DocsDocumentType product = new DocsDocumentType(1, "Product");
product.add(iPhone);
product.add(nexus);
this.documentTypes = new ArrayList<DocsDocumentType>();
this.documentTypes.add(identity);
this.documentTypes.add(product);
// Populating tableModel
for (DocsDocumentType docsDocumentType : documentTypes) {
TableModel tableModel = new TableModel();
tableModel.setName(docsDocumentType.getName());
for (DocsDocument docsDocument : docsDocumentType.getDocuments()) {
RowModel<String> rowModel = new RowModel<>();
rowModel.setName(String.valueOf(docsDocument.getId()));
tableModel.getRows().add(rowModel);
for (DocsData docsData : docsDocument.getDatas()) {
ColumnModel<DocsDescriptor> columnModel = findColumn(tableModel, docsData.getDescriptor());
if (columnModel == null) {
columnModel = new ColumnModel<>();
columnModel.setData(docsData.getDescriptor());
tableModel.getColumns().add(columnModel);
}
rowModel.getData().put(columnModel, docsData.getValue());
}
}
tables.add(tableModel);
}
}
private ColumnModel findColumn(TableModel tableModel, DocsDescriptor descriptor) {
for (ColumnModel columnModel : tableModel.getColumns()) {
if (descriptor.equals(columnModel.getData())) {
return columnModel;
}
}
return null;
}
public List<TableModel> getTables() {
return tables;
}
}
And view:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>TEST</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</h:head>
<h:body>
<f:event type="preRenderView" listener="#{test.start}"/>
<h:panelGroup id="bigArea" style="width : 100%">
<ui:repeat value="#{test.tables}" var="dt">
<p:panelGrid style="width : 750px">
<f:facet name="header">
<p:row>
<p:column style="width : 750px; text-align: left"><h:outputText value="#{dt.name}" /></p:column>
</p:row>
</f:facet>
<p:row>
<p:column>
<p:dataTable value="#{dt.rows}" var="row" emptyMessage="...">
<p:columns value="#{dt.columns}" var="col">
<f:facet name="header"><h:outputText value="#{col.data.name}"/></f:facet>
<h:outputText value="#{row.data[col]}" />
</p:columns>
</p:dataTable>
</p:column>
</p:row>
</p:panelGrid>
</ui:repeat>
</h:panelGroup>
</h:body>
</html>

Error : javax.el.PropertyNotFoundException: Target Unreachable, 'null' returned null [duplicate]

This question already has answers here:
Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable
(18 answers)
Closed 7 years ago.
I got this error below when I was running my JSF page.
javax.el.PropertyNotFoundException: Target Unreachable, 'null' returned null..
Warning: /createStaff.xhtml #33,125
value="#{staffBean.staff.firstName}": Target Unreachable, 'null'
returned null javax.el.PropertyNotFoundException: /createStaff.xhtml
#33,125 value="#{staffBean.staff.firstName}": Target Unreachable,
'null' returned null
I don't get why I will run into the error when I use value="#{staffBean.staff.firstName}". There is no problem when I use the value="#{staffBean.userName}" and value="#{staffBean.passWord}" above.
This is my createStaff.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:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Create Staff</title>
</h:head>
<h:body>
<f:view>
<h:form>
<p:panel id ="panel" header="Staff Creation">
<p:messages id="msgs" />
<h:panelGrid columns="3" columnClasses="label, value">
<h:outputText value="Username: *" />
<p:inputText id="username" value="#{staffBean.userName}" required="true" label="Username">
</p:inputText>
<p:message for="username" />
<h:outputLabel for="pwd1" value="Password 1: *" />
<p:password id="pwd1" value="#{staffBean.passWord}" match="pwd2" label="Password 1" required="true" feedback="true" />
<p:message for="pwd1" />
<h:outputLabel for="pwd2" value="Password 2: *" />
<p:password id="pwd2" value="#{staffBean.passWord}" label="Password 2" required="true" feedback="true" />
<p:message for="pwd2" />
<h:outputText value="First name: *" />
<p:inputText id="firstname" value="#{staffBean.staff.firstName}" required="true" label="Username">
</p:inputText>
<p:message for="firstname" />
<h:outputText value="Last name: *" />
<p:inputText id="lastname" value="#{staffBean.staff.lastName}" required="true" label="Username">
</p:inputText>
<p:message for="lastname" />
<h:outputText value="Last name: *" />
<p:selectOneRadio id="genderconsole" value="#{staffBean.staff.gender}" required="true">
<f:selectItem itemLabel="Male" itemValue="Male" />
<f:selectItem itemLabel="Female" itemValue="Female" />
</p:selectOneRadio>
<p:message for="genderconsole" />
<p:commandButton value="Create Staff"
id="ajax"
update="panel">
</p:commandButton>
</h:panelGrid>
</p:panel>
</h:form>
</f:view>
</h:body>
</html>
This is my StaffBean.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package managedbean;
import entities.Staff;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import sessionBean.staffSessionBeanLocal;
#Named(value = "staffBean")
#SessionScoped
//#ViewScoped
public class StaffBean implements Serializable {
#EJB
private staffSessionBeanLocal staffSession;
private String userName;
private String passWord;
private String loginStatus;
private Staff staff;
...........
////Code removed
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getLoginStatus() {
return loginStatus;
}
public void setLoginStatus(String loginStatus) {
this.loginStatus = loginStatus;
}
public Staff getStaff() {
return staff;
}
public void setStaff(Staff staff) {
this.staff = staff;
}
}
This is my staff entity.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
#Entity
public class Staff extends User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String imageURL;
#ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
private List<Roles> roles = new ArrayList<Roles>();
#Override
public Long getId() {
return id;
}
#Override
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Staff)) {
return false;
}
Staff other = (Staff) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entities.Staff[ id=" + id + " ]";
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public List<Roles> getRoles() {
return roles;
}
public void setRoles(List<Roles> roles) {
this.roles = roles;
}
}
This is my User class which Staff class extends from.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package entities;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
#MappedSuperclass
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String password;
private Timestamp joinDate;
private String userType;
private String gender;
private String email;
private String contactNo;
private String firstName;
private String lastName;
private Timestamp dOB;
private String address;
private String accountStatus;
private int numOfFailLogin;
private String maritalStatus;
private String activationCode;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof User)) {
return false;
}
User other = (User) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entities.User[ id=" + id + " ]";
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Timestamp getJoinDate() {
return joinDate;
}
public void setJoinDate(Timestamp joinDate) {
this.joinDate = joinDate;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getContactNo() {
return contactNo;
}
public void setContactNo(String contactNo) {
this.contactNo = contactNo;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Timestamp getdOB() {
return dOB;
}
public void setdOB(Timestamp dOB) {
this.dOB = dOB;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAccountStatus() {
return accountStatus;
}
public void setAccountStatus(String accountStatus) {
this.accountStatus = accountStatus;
}
public String getMaritalStatus() {
return maritalStatus;
}
public void setMaritalStatus(String maritalStatus) {
this.maritalStatus = maritalStatus;
}
public int getNumOfFailLogin() {
return numOfFailLogin;
}
public void setNumOfFailLogin(int numOfFailLogin) {
this.numOfFailLogin = numOfFailLogin;
}
public String getActivationCode() {
return activationCode;
}
public void setActivationCode(String activationCode) {
this.activationCode = activationCode;
}
}
You have no property firstName in your entity staff
UPDATE:
Looks like your staffobject is null add:
#PostConstruct
public void init() {
staff = new Stuff();
}
The error suggests that when the "firstName" is being accessed, it cannot be reached. So the "Staff" has not been constructed yet.
Add a method to your managed bean, this will resolve the issue.
#PostConstruct
public void init() {
staff= new Staff ();
}
For better understanding of why you should do it that way and not
Staff staff = new Staff();
JSF - what is the difference between #PostConstruct and direct method call from constructor?

Catching PrimeFaces's spinner value inside repeat structure

I'm using Primefaces and spinner component. My problem is that the spinner value is not set in the bean, if it's inside an iteration structure. My spinner is inside ui:repeat.
In the end, the problem is how to deal with different form controls mapping to the same property in bean.
<h:form>
<ui:repeat var="item" value="#{myBean.items}">
<p:spinner size="2" min="1" max="50" style="width:75px" value="#{cartBean.quantityToOrder}"/>
<p:commandButton value="Add to cart" action="#{cartBean.saveItemToCart(item)}" ajax="false"/>
</ui:repeat>
</h:form>
and my bean
#ManagedBean
#SessionScoped
public class CartBean extends BaseBean {
private int quantityToOrder;
//setter, getter...
//When called quantityToOrder = 0 always
public void saveItemToOrder(Item item) {
quantityToOrder IS 0.
}
}
I suspect it has to do with form submission, I have tried a form enclosing all elements in the collection and also a form enclosing any of the spinners + button. The generated client IDs are distinct for all spinners.
Any help would be appreciated.
Put a System.out.println("quantity: " + quantityToOrder) on your setQuantityToOrder(int quantityToOrder) method and will will see the problem. The value of the last spinner will prevail over the others because all the spinners are pointed to the same property (cartBean.quantityToOrder).
Try moving the quantityToOrder to the Item as follows:
<h:form id="mainForm">
<ui:repeat value="#{cartBean.items}" var="item">
<p:outputLabel value="#{item.name}: " for="sp" />
<p:spinner id="sp" size="2" min="1" max="50" style="width:75px" value="#{item.quantityToOrder}" />
<p:commandButton value="Add to cart" action="#{cartBean.saveItemToOrder(item)}" process="#this, sp" update=":mainForm:total" />
<br />
</ui:repeat>
Total: <h:outputText id="total" value="#{cartBean.quantityToOrder}" />
</h:form>
The cartBean:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class CartBean implements Serializable {
private List<CartItem> items;
private int quantityToOrder;
#PostConstruct
public void setup() {
items = new ArrayList<CartItem>();
items.add(new CartItem(1, "A"));
items.add(new CartItem(2, "B"));
items.add(new CartItem(3, "C"));
}
public void saveItemToOrder(CartItem item) {
//do whatever you want to do with the item quantity.
System.out.println("Qtd of " + item.getName() + ": " + item.getQuantityToOrder());
//to calculte the qtd of items on the cart.
quantityToOrder = 0;
for (CartItem cartItem : items) {
quantityToOrder += cartItem.getQuantityToOrder();
}
}
public List<CartItem> getItems() {
return items;
}
public void setItems(List<CartItem> items) {
this.items = items;
}
public int getQuantityToOrder() {
return quantityToOrder;
}
public void setQuantityToOrder(int quantityToOrder) {
this.quantityToOrder = quantityToOrder;
}
}
The CartItem:
import java.io.Serializable;
public class CartItem implements Serializable {
private Integer id;
private Integer quantityToOrder;
private String name;
public CartItem(Integer id, String name) {
this.id = id;
this.name = name;
quantityToOrder = 0;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getQuantityToOrder() {
return quantityToOrder;
}
public void setQuantityToOrder(Integer quantityToOrder) {
this.quantityToOrder = quantityToOrder;
}
#Override
public int hashCode() {
int hash = 7;
hash = 67 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CartItem other = (CartItem) obj;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
return false;
}
return true;
}
}

primefaces autocomplete not showing in textBox

I have tried to implement the autocomplete feature in primefaces but suggestions do not show up in my textbox. Can someone show me what I'm missing. theses are codes
udateCategory.xhtml
<p:panel header="Type in Category to Edit" >
<p:outputLabel value="Category Name"/>
<p:autoComplete value="#{categoryBean.selectedCategory}"
completeMethod="#{categoryBean.completeCategory}"
var="cat"
itemLabel="#{cat.categoryName}"
itemValue="#{cat}"
converter="#{catConverter}"
forceSelection="true"/>
<p:commandButton value="Update" action="#{category.saveCategory}"/>
</p:panel>
CategoryBean
public class CategoryBean implements Serializable{
private Category selectedCategory;
/**
* Creates a new instance of CategoryBean
*/
public CategoryBean() {
}
public List<Category> completeCategory (String query){
CategoryManager manager = new CategoryManager();//an instance of the manager
List<Category> suggestions = new ArrayList<>();//an instance of list
List<Category> allCategory = new ArrayList<>(); //populate the allCategory with data fro db
allCategory = manager.getAllCategory();
//checck to see if data exist in allCategory
if(!allCategory.isEmpty()){
System.out.println("kobla : allcategory has data");
}
else
{
System.out.println("kobla: no data in alcategory");
}
for(Category cat : allCategory){
if(cat.getCategoryName().startsWith(query)){
suggestions.add(cat);
}
}
//check to see if data exists in sugestions
if (!suggestions.isEmpty()) {
System.out.println("kobla : suggestions has data");
} else {
System.out.println("kobla: no data in suggestions");
}
return suggestions;
}
/**
* #return the selectedCategory
*/
public Category getSelectedCategory() {
return selectedCategory;
}
/**
* #param selectedCategory the selectedCategory to set
*/
public void setSelectedCategory(Category selectedCategory) {
this.selectedCategory = selectedCategory;
}
}
CategoryConverter
public class CategoryConverter implements Converter{
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value.trim().equals("")){
return null;
}
else{
try{
int id = Integer.parseInt(value);
List<Category> myCategory = new ArrayList<>();//
myCategory = new CategoryManager().getAllCategory();//load data fro db
for(Category cat : myCategory){
if(cat.getCategoryID() == id){
return cat;
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null || value ==""){
return null;
}
else
{
return String.valueOf(((Category)value).getCategoryName());
}
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
this works for me
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class CategoryBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Category selectedCategory;
#PostConstruct
public void init(){
selectedCategory = new Category();
}
public void saveCategory(){
System.out.println("saved "+this.selectedCategory);
}
public List<Category> completeCategory(String query) {
CategoryManager manager = new CategoryManager();// an instance of the
// manager
List<Category> suggestions = new ArrayList<>();// an instance of list
List<Category> allCategory = new ArrayList<>(); // populate the
// allCategory with data
// fro db
allCategory = manager.getAllCategory();
// checck to see if data exist in allCategory
if (!allCategory.isEmpty()) {
System.out.println("kobla : allcategory has data");
} else {
System.out.println("kobla: no data in alcategory");
}
for (Category cat : allCategory) {
if (cat.getCategoryName().startsWith(query)) {
suggestions.add(cat);
}
}
// check to see if data exists in sugestions
if (!suggestions.isEmpty()) {
System.out.println("kobla : suggestions has data");
} else {
System.out.println("kobla: no data in suggestions");
}
return suggestions;
}
/**
* #return the selectedCategory
*/
public Category getSelectedCategory() {
return selectedCategory;
}
/**
* #param selectedCategory
* the selectedCategory to set
*/
public void setSelectedCategory(Category selectedCategory) {
this.selectedCategory = selectedCategory;
}
}
and
import java.io.Serializable;
public class Category implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int categoryID;
private String categoryName;
public int getCategoryID() {
return categoryID;
}
public void setCategoryID(int categoryID) {
this.categoryID = categoryID;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public Category(int categoryID, String categoryName) {
super();
this.categoryID = categoryID;
this.categoryName = categoryName;
}
public Category() {
super();
}
#Override
public String toString() {
return "Category [categoryID=" + categoryID + ", categoryName="
+ categoryName + "]";
}
}
and
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
#ManagedBean
#RequestScoped
public class CategoryConverter implements Converter, Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value.trim().equals("")){
return null;
}
else{
try{
int id = Integer.parseInt(value);
List<Category> myCategory = new ArrayList<>();//
myCategory = new CategoryManager().getAllCategory();//load data fro db
for(Category cat : myCategory){
if(cat.getCategoryID() == id){
return cat;
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
return null;
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if(value == null || value ==""){
return null;
}
else
{
return String.valueOf(((Category)value).getCategoryName());
}
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
and
<!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:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head></h:head>
<h:body>
<h:form>
<p:outputLabel value="Category Name" />
<p:autoComplete
value="#{categoryBean.selectedCategory}"
completeMethod="#{categoryBean.completeCategory}"
var="cat"
itemLabel="#{cat.categoryName}"
itemValue="#{cat}"
converter="#{categoryConverter}"
forceSelection="true" />
<p:commandButton value="Update" action="#{categoryBean.saveCategory}" />
</h:form>
</h:body>
</html>

Resources