Create ZKtodo-0.9.2_Project by "MySQL,JavaEE6-EJB3.1"
Todo serves as optimal reference example of "How to use database in ZK" as an introduction to ZK.
Here, I will show you an example of ”JavaEE6 ・EJB3.1”, “use of global JNDI” as database CRUD access technic.
I used zktodo-0.9.2 (URL: http://books.zkoss.org/wiki/ZK_Getting_Started/Creating_a_Database-driven_Application) as a template, but I changed DataBase from HSQLDB to MySQL and I changed primary key from String to Long.
I used article ”ZK with EJB3.1 running on Glassfish“ ( http://javadude.wordpress.com/2011/01/11/zk-with-ejb3-1-running-on-glassfish/) as a reference.
I used NetBeans7.0.1 , GlassFish3.1.1 and ZK5.09CE.
We can download source code from here .
We can create MySQL Database from /web/data/todoejb.sql .
1. Create Project
We use NetBeans7.0.1( installed with ZK509CE plugin) and we use GlassFish3.1.1 as application server.
We create project “ZKtodoEvent” using “ZK: JavaEE6 Application” as template.
Java source code version is JDK6.
2. Create Database
First we create database( tudoejb ) in MySQL
DDL definition is following.
/*DDL Information*/
CREATE TABLE `todoevent` (
`id` bigint(20) NOT NULL,
`name` varchar(50) DEFAULT NULL,
`priority` int(11) DEFAULT NULL,
`date` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3. Create entity
At IDE, we enter into wizard of “creation of entity class” by new -- >> new entity class creation.
Class name: TodoEvent
Package: org.zkoss.todo
Make check in “Create parsistence Unit” check box and click “Next” button.

“ZKtodoEventPU” is entered into PU name field and requested to select Data Source.

When clicked “new Data Source” ,then “Create Data Source” is pop uped.

When clicked “new Database Connection” ,then “New Connection Wizard” is pop uped.

When clicked “new Database Connection” ,then “New Connection Wizard” pop up appears.
Here we select MySQL (Connector/J driver) . Then click "Next" button.

Here we customize connection.
We enter todoejb in Database field.
Enter password
and click "Test Connection" to confirm connection.
Then click "Next" button.

We enter “todoejb” into Database field.
Then we confirm connection,then click “Finish” button.

We complete by clicking "OK" and next "Finish",then project is as following
Under src folder of Project,there created conf folder and persistence.xml is placed into it.
persistence.xml
jdbc/todoejb
false
Here is unneeded code.
<property name="eclipselink.ddl-generation" value="create-tables"/>
So
please remove this.
At the root of project , setup folder is created and sun-resources.xml is placed into it.
sun-resources.xml
In Entity(TodoEvent.java) created by IDE, there defined only id field.
We add necessary fileds( name, priority, date).
@Temporal(TemporalType.TIMESTAMP) is needed at date field.
If not this annotation,then error message "A temporal attribute must be marked with @Temporal annotation." apperas.
We implement setter, getter method of the added fields.
4. Create Session facade
At IDE, we enter into wizard of “creation of entity class Session Bean” by new -->>Session Beans For new Entity classes creation at the category "Enterprise JavaBeans".

As available Entity classes,there is “org.zkoss.toto.TodoEvent”,we move this class to selected Entity classes window.
Then click “Next” button.

Click “Finish” button.

Then 2 classes AbstractFacade.java,TodoEventFacade.java are added to this project.
5. Copying of zul files from original ZKtodo-0.9.2 Project
6. Refactoring copy of DAO class( EventDAO.java), Controller class( EventController.java) from original ZKtodo-0.9.2 Project.
7. Automatic generation of code into EventDAO.java that call “TodoEventFacade” using "global JNDI" by NetBeans
1. Right click at blank space
2. Select item “Insert Code"
3. Select item “Call Enterprise Bean”
4. List of project appears and if we select project( ZKtodoEvent ),there appear EJBs,so we select needed EJB( TodoEventFacade).
Following is auto generated code.
// TodoEventFacade todoEventFacade = lookupTodoEventFacadeBean();
TodoEventFacade tEF = lookupTodoEventFacadeBean();
private TodoEventFacade lookupTodoEventFacadeBean() {
try {
Context c = new InitialContext();
return (TodoEventFacade) c.lookup("java:global/ZKtodoEvent/TodoEventFacade!org.zkoss.todo.TodoEventFacade");
} catch (NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
throw new RuntimeException(ne);
}
}
At the end of web.xml,here placed unneeded code.why?
TodoEventFacade
Session
#TodoEventFacade
We this becomes obstacle of project,must remove this.
8.Completed EventDAO.java and EventController.java
How simple these codes are!!
EventDAO.java
package org.zkoss.todo;
/**
* Event DAO.
*
* @author robbiecheng
*/
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class EventDAO {
// TodoEventFacade todoEventFacade = lookupTodoEventFacadeBean();
TodoEventFacade tEF = lookupTodoEventFacadeBean();
private TodoEventFacade lookupTodoEventFacadeBean() {
try {
Context c = new InitialContext();
return (TodoEventFacade) c.lookup("java:global/ZKtodoEvent/TodoEventFacade!org.zkoss.todo.TodoEventFacade");
} catch (NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
throw new RuntimeException(ne);
}
}
public List<TodoEvent> findAll() {
List allEvents = tEF.findAll();
return allEvents;
}
public void delete(TodoEvent evt) {
tEF.remove(evt);
}
public void insert(TodoEvent evt) {
tEF.create(evt);
}
public void update(TodoEvent evt) {
tEF.edit(evt);
}
}
EventController.java
package org.zkoss.todo;
/**
* Event Controller.
*
* @author robbiecheng
*/
import java.util.List;
import java.util.UUID;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.ForwardEvent;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;
public class EventController extends GenericForwardComposer {
private static final long serialVersionUID = -9145887024839938515L;
private TodoEvent current = new TodoEvent();
private EventDAO eventDao = new EventDAO();
private Textbox name;
private Intbox priority;
private Datebox date;
public void onSelect$box(Event e) {
ForwardEvent forwardEvt = (ForwardEvent) e;
Listbox box = (Listbox) forwardEvt.getOrigin().getTarget();
if (box.getSelectedItem() != null) {
current = (TodoEvent) box.getSelectedItem().getValue();
refresh();
}
}
private void refresh() {
name.setValue(current.getName());
priority.setValue(current.getPriority());
date.setValue(current.getDate());
}
public TodoEvent getCurrent() {
return current;
}
public void setCurrent(TodoEvent current) {
this.current = current;
}
public List<TodoEvent> getAllEvents() {
return eventDao.findAll();
}
private boolean validate(TodoEvent current2) {
if(current.getName() == null ||
current.getName().length() <= 0 ||
current.getDate() == null) {
try {
Messagebox.show("All fields cannot be empty, please check fields.");
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
}
return true;
}
public void onClick$add() {
if (validate(current)) {
// insert into database
eventDao.insert(current);
}
}
public void onClick$update() {
if (current != null && validate(current)) {
// update database
eventDao.update(current);
}
}
public void onClick$delete() {
if (current != null && validate(current)) {
eventDao.delete(current);
}
}
}