ZK with EJB3.1 running on Glassfish (Part 2)

In part 1 we connected a web application to a database using an EJB for reading access, deployed on a Glassfish Server. In part 2 we do some modifications to create a true CRUD application by adding add, delete and update.

Pre-Requirements:

  • Netbeans 6.7 or later
  • Installed ZK plugin (link)
  • Glassfish V3 or later
  • Netbeans Project from Part 1 (link)

Tutorial:

  1. EJB modifications
    are not required because for the basic CRUD functions we will use the provide abstract facade.

    package ejb;
    
    import java.util.List;
    import javax.persistence.EntityManager;
    
    public abstract class AbstractFacade<T> {
     private Class<T> entityClass;
    
     public AbstractFacade(Class<T> entityClass) {
     this.entityClass = entityClass;
     }
    
     protected abstract EntityManager getEntityManager();
    
     public void create(T entity) {
     getEntityManager().persist(entity);
     }
    
     public void edit(T entity) {
     getEntityManager().merge(entity);
     }
    
     public void remove(T entity) {
     getEntityManager().remove(getEntityManager().merge(entity));
     }
    
     public T find(Object id) {
     return getEntityManager().find(entityClass, id);
     }
    
     public List<T> findAll() {
     javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
     cq.select(cq.from(entityClass));
     return getEntityManager().createQuery(cq).getResultList();
     }
    
     public List<T> findRange(int[] range) {
     javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
     cq.select(cq.from(entityClass));
     javax.persistence.Query q = getEntityManager().createQuery(cq);
     q.setMaxResults(range[1] - range[0]);
     q.setFirstResult(range[0]);
     return q.getResultList();
     }
    
     public int count() {
     javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
     javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
     cq.select(getEntityManager().getCriteriaBuilder().count(rt));
     javax.persistence.Query q = getEntityManager().createQuery(cq);
     return ((Long) q.getSingleResult()).intValue();
     }
    
    }
    
    
  2. Modification of the zul file
    We add a button for delete and a grid with the 3 table columns, plus update and create buttons.

    <?xml version="1.0" encoding="UTF-8"?>
    
    <zk xmlns="http://www.zkoss.org/2005/zul">
     <?init?>
     <window id="list" apply="controller.indexController" title="Customer List">
     <listbox id="lst" width="100%" >
     <listhead sizable="true">
     <listheader id="col1" label="Company"/>
     <listheader id="col2" label="First Name" />
     <listheader id="col3" label="Last Name" />
     </listhead>
     </listbox>
    
     <button id="btnDelete" label="Delete record"/>
     <separator bar="true"/>
    
     <grid width="40%">
     <columns>
     <column label=""/>
     <column label=""/>
     </columns>
     <rows>
     <row>
     <label value="Company:" />
     <textbox id="txtCompany" value=""/>
     </row>
     <row>
     <label value="First:" />
     <textbox id="txtFirst" value=""/>
     </row>
     <row>
     <label value="Last:" />
     <textbox id="txtLast" value=""/>
     </row>
     </rows>
     </grid>
    
     <button id="btnUpdate" label="Update record"/>
     <button id="btnAdd" label="Add record"/>
     </window>
    </zk>
    
  3. Modification to the controller class
    We need to add variables for the additional components, create a separate instance of the model to update the listbox without re-reading the data from the DB when changes are applied.

    package controller;
    
    import ejb.customerZK;
    import ejb.customerFacade;
    import java.util.ArrayList;
    import java.util.List;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import org.zkoss.zk.ui.Component;
    import org.zkoss.zk.ui.event.Event;
    import org.zkoss.zk.ui.util.GenericForwardComposer;
    import org.zkoss.zul.Button;
    import org.zkoss.zul.ListModelList;
    import org.zkoss.zul.Listbox;
    import org.zkoss.zul.Listcell;
    import org.zkoss.zul.Listitem;
    import org.zkoss.zul.ListitemRenderer;
    import org.zkoss.zul.Textbox;
    
    public class indexController extends GenericForwardComposer {
    
     Context context;
     customerFacade facade;
     List<customerZK> customer = null;
     ListModelList model;
     private Listbox lst;
     private Textbox txtLast;
     private Textbox txtFirst;
     private Textbox txtCompany;
    
     @Override
     public void doAfterCompose(Component comp) throws Exception {
     super.doAfterCompose(comp);
    
     context = new InitialContext();
    
     try {
     facade = (customerFacade) context.lookup("java:global/ZK_EJB_WEB/customerFacade");
    
     // Read all records and store it in a arraylist
     customer = new ArrayList();
     customer.addAll(facade.findAll());
    
     // Set listmodel for the ZK list component
     model = new ListModelList(customer);
     lst.setModel(model);
    
     // Custom renderer
     ListitemRenderer listitem = new ListitemRenderer() {
    
     @Override
     public void render(Listitem item, Object data) throws Exception {
     item.setValue(data);
     item.appendChild(new Listcell(((customerZK) data).getCompanyName()));
     item.appendChild(new Listcell(((customerZK) data).getFirstName()));
     item.appendChild(new Listcell(((customerZK) data).getLastName()));
     }
     };
     lst.setItemRenderer(listitem);
    
    } catch (Exception e) {
     System.out.println(e.getMessage());
     }
     }
    
     public void onSelect$lst(Event evt) throws InterruptedException {
     // read values from selected record
     txtLast.setValue(((customerZK) lst.getSelectedItem().getValue()).getLastName());
     txtFirst.setValue(((customerZK) lst.getSelectedItem().getValue()).getFirstName());
     txtCompany.setValue(((customerZK) lst.getSelectedItem().getValue()).getCompanyName());
     }
    
     public void onClick$btnDelete(Event evt) throws InterruptedException {
     System.out.println("Deleting ID: " + ((customerZK) lst.getSelectedItem().getValue()).getId());
     // persist
     facade.remove((customerZK) lst.getSelectedItem().getValue());
     // update listmodel
     model.remove((customerZK) lst.getSelectedItem().getValue());
     }
    
     public void onClick$btnUpdate(Event evt) throws InterruptedException {
     customerZK modCustomer = new customerZK();
    
     // read values from textbox
     modCustomer.setId(((customerZK) lst.getSelectedItem().getValue()).getId());
     modCustomer.setCompanyName(txtCompany.getValue());
     modCustomer.setFirstName(txtFirst.getValue());
     modCustomer.setLastName(txtLast.getValue());
    
     // persist
     facade.edit(modCustomer);
     // update listmodel
     model.set(model.indexOf((customerZK) lst.getSelectedItem().getValue()) , modCustomer);
    
     }
    
     public void onClick$btnAdd(Event evt) throws InterruptedException {
    
     customerZK modCustomer = new customerZK();
    
     modCustomer.setCompanyName(txtCompany.getValue());
     modCustomer.setFirstName(txtFirst.getValue());
     modCustomer.setLastName(txtLast.getValue());
    
     // persist
     facade.create(modCustomer);
     // update listmodel
     model.add(modCustomer);
    
     }
    }
    
  4. Run the application

    Running ZK application

Remarks:

About these ads

2 thoughts on “ZK with EJB3.1 running on Glassfish (Part 2)

  1. Hi dude,

    why do you prefer to lookup the facade instead of injecting it? Like:
    @EJB customerFacade facade;

    about your first final remarks, a smarter way could be to use the zk Binder and the @ annotations in the zul?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s