I am presently working on my AISD project, and i am using jsf(primefaces) spring and jpa to build the system. i would like to commend the efforts of the brains behind jsf 2.0 and primefaces (1.* and 2.*)
in particular for making the life of java web devs much easier. I remember back in the days the first versions of jsf were simply nightmares, which lead my cohorts and i to move to frameworks like wicket
.
This blog post seeks to show how to populate a jsf Combo box with values from a database table and also you would notice that the implementation for this case includes both jsf 1.* and jsf 2.*. I assume some familiarity with spring jpa and jsf.
Most relational database records have a primary key to uniquely identify it. This key appears on other tables as foreign keys. In my application i needed to display one or more of the attributes of a record from a table on a form and persist its unique identifier .
Below i provide some sample code that gives some hint on how this can be achieved using plain old java objects..
First lets paint the screen.. For JSF 1.*:
<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.prime.com.tr/ui">
<head>
<p:resources />
</head>
<body>
<h:form prependId="false" styleClass="cmxform">
<fieldset>
<legend> </legend>
<p:panel id="panel" header="Combo Box Example">
<h:panelGrid columns="2" columnClasses="label,value" styleClass="grid">
<h:outputLabel for="cb" value="comboItem" />
<h:selectOneMenu id="selectOneCb" value="#{pageBean.model.modelid}">
<f:selectItem itemLabel="Select Model" itemValue="" />
<f:selectItems value="#{pageBean.myModelValues}" />
</h:selectOneMenu>
</h:panelGrid>
</p:panel>
</fieldset>
</h:form>
</body>
</html>
For JSF 2.* this is even easier (thanks to Çağatay Çivici the primefaces lead for pointing this out to me
):
<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.prime.com.tr/ui">
<head>
<p:resources />
</head>
<body>
<h:form prependId="false" styleClass="cmxform">
<fieldset>
<legend> </legend>
<p:panel id="panel" header="Combo Box Example">
<h:panelGrid columns="2" columnClasses="label,value" styleClass="grid">
<h:outputLabel for="cb" value="comboItem" />
<h:selectOneMenu id="selectOneCb" value="#{pageBean.model.modelid}">
<f:selectItem itemLabel="Select Model" itemValue="" />
<f:selectItems value="#{pageBean.mlist}" var="model" itemLabel="#{model.modelvalue}" itemValue="#{model.modelId}"/>
</h:selectOneMenu>
</h:panelGrid>
</p:panel>
</fieldset>
</h:form>
</body>
</html>
Next lets define the backing page bean… For JSF 1.* this is ok :
@Component("pageBean")
@Scope("request")
public class PageBean implements Serializable {
private model = new Model();
private ModelService modelService;
private Map<String, String> myModelValues = new HashMap<String, String>();
private List<Model> mList;
public PageBean(){
}
@Autowired
public PageBean(ModelService modelService){
this. modelService = modelService;
mList = modelService.findAll();
for (Model m : mList) {
myModelValues.put(m.getmyModelValue(), m.getmyModelId());
}
}
public Map<String, String> getMyModelValues() {
return myModelValues;
}
public void setMyModelValues(Map<String, String> myModelValues) {
this.myModelValues= myModelValues;
}
public Model getModel() {
return model;
}
public void setModel(Model model) {
this.model = model;
}
}
For JSF 2.* it is even better => You don’t need use a Map or Hash Map as the case may be above (thanks to Çağatay Çivici the primefaces lead for pointing this out ):
@Component("pageBean")
@Scope("request")
public class PageBean implements Serializable {
private model = new Model();
private ModelService modelService;
private List<Model> list;
public PageBean(){
}
@Autowired
public PageBean(ModelService modelService){
this. modelService = modelService;
list = modelService.findAll();
}
public List<Model> getList() {
return list;
}
public Model getModel() {
return model;
}
public void setModel(Model model) {
this.model = model;
}
}
Below is a service interface to define the the findAll method:
public interface ModelService {
public List< Model> findAll();
}
Next the implementation for the Model Service Interface:
@Service("modelService")
public ModelServiceImpl implements ModelService {
private ModelDAO modeldao;
@Autowired
public ModelServiceImpl(ModelDAO modeldao) {
this. modeldao = modeldao;
}
@Transactional(readOnly = true)
public List<Model> findAll() {
return modeldao.findAll();
}
}
The Data Access object interface:
public interface ModelDAO {
public List< Model> findAll();
}
The Data Access object implementation proper:
@Repository
public class ModelDAOImpl implements ModelDAO {
@PersistenceContext
protected EntityManager entityMgr;
public EntityManager getEntityMgr() {
return entityMgr;
}
public void setEntityMgr(EntityManager entityMgr) {
this.entityMgr = entityMgr;
}
public List<Model> findAll() {
Query query = entityMgr.createNamedQuery("Model.findAll");
return query.getResultList();
}
}
Finally lets define the jpa model object:
@Entity
@Table(name = "MODEL")
@NamedQuery(name = "Model.findAll", query = "SELECT m FROM Model m") // this query returns distinct values from the database.
public class Model implements Serializable {
@Id
@Basic(optional = false)
@Column(name = "MODEL_ID")
private String modelId;
@Basic(optional = false)
@Column(name = "MODEL_VALUE")
private String modelValue;
public Model() {
}
public Model(String modelId, String modelValue) {
this.modelId = modelId;
this.model = modelValue;
}
public String getModelId() {
return modelId;
}
public void setModelId(String modelId) {
this.modelId = modelId;
}
public String getModelValue() {
return modelValue;
}
public void setModelValue(String modelValue) {
this. modelValue = modelValue;
}
}
The code above steps through it all… Ciao for now..