In this tutorial you will learn how to make a simple CRUD application using Java Server Faces (JSF), Primefaces framework, Java Persistent API (JPA) & MySQL database management system.
Our app will be a basic app that will create, read, update and delete from a MySQL database.
To follow up this tutorial, you need the following:
NB: J2EE is not Java SE nor JavaScript, don’t get confused😁
Before starting, we assume you have setup your database and configured your servers.
The first thing to do is creating a connection resource that will permit us link our database to our app.
We will open our Glassfish server admin console by typing this url in our browser.
http://localhost:4848
Create a new connection pool called “CRUD”
Creating a new connection pool from our Glassfish server admin panel
Move to the next step and enter your database server username, password and URL. Here is the database URL:
jdbc:mysql://localhost:3306/crud?zeroDateTimeBehavior=convertToNull
Creating a new connection pool from our Glassfish server admin panel
Then create a JBC Resource called CRUD_App
.
We are done creating our connection resource.
Next, we are creating a connection between our Netbeans IDE and our database.
We are done creating our database connection.
Let’s move on to building our app.
Open Netbeans and create a new Enterprise Application.
Creating a new enterprise application — Choose project
We will call our project “CRUD” .
Creating a new enterprise application — Server & settings
Check “Create EJB Module” and “Create web application module”. The EJB module will serve as our bean container and the web module as our view container. For further explanation you can follow this link
At this point, we’ve successfully created our project, here’s the beginning of some real stuff.
Let’s have a look at our database 👀
Book table from MySQL database
Our database “CRUD” contains one table called “Book” that has 6 columns.
Now, let’s create our Entity classes from our database. This is a Java class that is mapped to a database table.
Creating entity classes from our database
Do you remember the configurations we did in our glassfish server above? Let’s see is use now!
The next steps is selecting our database table to create our entity class. In Data source field, we will select our CRUD_App
connection pool we created above.
Add the book table to selected tables and move to the next step.
Let’s generate our class into a new package called “entities”
Set the association fetch to “default” and the collection type to java.util.list
(this describes the way in which we shall retrieve our entities from our database).
We’ve successfully generated our Entity class “Book”, let’s have a look at it. It contains Named Queries, entity variables with their constraints, a constructor, getters and setters and some few functions.
A Session Bean is a server-side component providing services to clients. It can provide the different steps for an application workflow:
To create our Session bean, create a new file & choose “Session Beans For Entity Classes”.
Creating a session bean
Chose the corresponding entity class (Book) and move to the next step
Creating a session bean from an existing entity class
Let’s create our Session bean in a new package called sessionbean
. Set the Interface to Local
.
But why Local? Simply because the client is deployed in the same virtual machine. e.g. A Web application deployed in the same application server as the Session Bean
Finalizing our Session bean
Now, let’s have a look at our new package, we can find three new classes:
We are done with the “initialization” of our EJB module. Let’s move to our web module (WAR) and create our views and controllers.
Confusing? Don’t worry, your doubts shall be cleared as we proceed😉
In the WAR module, right click on the “Web Pages” folder and create a new JSF page called “index.xhtml” and delete the existing index.html
file.
Creating our new JSF page
JavaServer Faces (JSF) is a new standard Java framework for building Web applications. It simplifies development by providing a component-centric approach to developing Java Web user interfaces.
This is how our folder should look like
In the “Configuration Files” folder, open the web.xml
file and make sure default page is set to the new jsf page we created.
<welcome-file-list><welcome-file>faces/index.xhtml</welcome-file></welcome-file-list>
Managed Bean are components that are managed by JavaServer Faces technology
Managed Bean is a regular Java Bean class registered with JSF. In other words, Managed Bean is a Java bean managed by JSF framework. Managed beans contain the getter and setter methods, business logic, or even a backing bean (a bean contains all the HTML form value).
Managed beans works as Model for UI component. Managed Bean can be accessed from JSF page.
We right click on our WAR module to create a new file, and we select “JSF Managed Bean” from the list
Let’s create a new package called controller
and call managed bean bookController
. Set the scope as Session
Now, let’s inject our Session bean by inserting the code below inside our managed bean class:
@EJBprivate BookFacadeLocal booksFacade;
We can observe a strange word, @EJB
. This is what is called an annotation and is used to inject our Session bean into the managed bean.
Next, we create a new book object, and declare all its attributes with their getters and setters as shown below:
package controller;
import entities.Book;import javax.inject.Named;import javax.enterprise.context.SessionScoped;import java.io.Serializable;import java.util.List;import javax.ejb.EJB;import sessionbean.BookFacadeLocal;
@Named(value = "bookController")@SessionScopedpublic class bookController implements Serializable {
@EJBprivate BookFacadeLocal booksFacade;
private Book book = new Book();private String name;private String author;private Integer year;private String category;private long price;
public bookController() {}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getAuthor() {return author;}
public void setAuthor(String author) {this.author = author;}
public Integer getYear() {return year;}
public void setYear(Integer year) {this.year = year;}
public String getCategory() {return category;}
public void setCategory(String category) {this.category = category;}
public long getPrice() {return price;}
public void setPrice(long price) {this.price = price;}
}
Still under our WAR module, let’s add a new library called Primefaces to our project. Right click on the Libraries folder, then select the “Add library” option and add “Primefaces 6.2”.
PrimeFaces is a popular open source framework for JavaServer Faces featuring over 100 components, touch optimized mobilekit, client side validation, theme engine and more.
This framework will provide us UI components to help us build our views and achieve our goal faster.
At this step, we are going to create our CRUD (Create Read Update and Delete) functions.
Before all, let’s create a method emptyVariable()
. This method will help us empty our variables when needed
public void emptyVariables() {this.author = "";this.category = "";this.name = "";this.price = 0;this.year = 0;}
First, the C. Let’s create the createBook()
method.
public String createBook() {this.book.setAuthor(this.author);this.book.setCategory(this.category);this.book.setName(this.name);this.book.setPrice(this.price);this.book.setYear(this.year);this.booksFacade.create(this.book);this.emptyVariables();return "index.xhtml?faces-redirect=true";}
In this function, we can see that the book
object we created before, has its attributes assigned values for the new entity to be created using its setters.
Second, the R. Let’s create the getAllBooks()
method.
public List<Book> getAllBooks() {return this.booksFacade.findAll();}
Thridly, the U. Let’s create the updateBook()
method.
public String updateBook(Book book) {this.booksFacade.edit(this.book);return "index.xhtml?faces-redirect=true";}
The last but not the least, the D. deleteBook()
public String deleteBook(Book book) {this.booksFacade.remove(book);return "index.xhtml?faces-redirect=true";}
We can make some observations on the above functions.
i. The CRUD functions we created only serve as bridges to our Entity Session Beans
ii. Our CRUD functions return a string. This is simply to refresh our page to be able to observe the results of our functions
package controller;
import entities.Book;import javax.inject.Named;import javax.enterprise.context.SessionScoped;import java.io.Serializable;import java.util.List;import javax.ejb.EJB;import sessionbean.BookFacadeLocal;
@Named(value = "bookController")@SessionScopedpublic class bookController implements Serializable {
@EJBprivate BookFacadeLocal booksFacade;
private Book selectedBook;
private Book book = new Book();private String name;private String author;private Integer year;private String category;private long price;
public bookController() {}
public Book getSelectedBook() {return selectedBook;}
public void setSelectedBook(Book selectedBook) {this.selectedBook = selectedBook;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getAuthor() {return author;}
public void setAuthor(String author) {this.author = author;}
public Integer getYear() {return year;}
public void setYear(Integer year) {this.year = year;}
public String getCategory() {return category;}
public void setCategory(String category) {this.category = category;}
public long getPrice() {return price;}
public void setPrice(long price) {this.price = price;}
public List<Book> getAllBooks() {return this.booksFacade.findAll();}
public void emptyVariables() {this.author = "";this.category = "";this.name = "";this.price = 0;this.year = 0;}
public String createBook() {this.book.setAuthor(this.author);this.book.setCategory(this.category);this.book.setName(this.name);this.book.setPrice(this.price);this.book.setYear(this.year);this.booksFacade.create(this.book);this.emptyVariables();return "index.xhtml?faces-redirect=true";}
public String updateBook() {this.booksFacade.edit(this.selectedBook);return "index.xhtml?faces-redirect=true";}
public String deleteBook(Book book) {this.booksFacade.remove(book);return "index.xhtml?faces-redirect=true";}}
Now, let’s build our index page. We will create a form to add data to our table “Book” and a datatable to display our table Book. The table will also permit us update and delete a chosen book.
<html xmlns="http://www.w3.org/1999/xhtml"xmlns:h="http://xmlns.jcp.org/jsf/html"xmlns:p="http://primefaces.org/ui"xmlns:f="http://xmlns.jcp.org/jsf/core"><h:head><title>CRUD</title></h:head><h:body><h1>CRUD</h1><h:form><h:panelGrid columns="12" cellpadding="5"><h:outputText value="Name " /><p:inputText value="#{bookController.name}"/>
<h:outputText value="Author " /><p:inputText value="#{bookController.author}" />
<h:outputText value="Category " /><p:inputText value="#{bookController.category}"/>
<h:outputText value="Year " /><p:inputText value="#{bookController.year}"/>
<h:outputText value="Price " /><p:inputText value="#{bookController.price}"/>
<p:commandButton value="Add" icon="fa fa-fw fa-plus" action="#{bookController.createBook()}"/></h:panelGrid></h:form>
<h:form id="form"><p:dataTable value="#{bookController.getAllBooks()}" var="book" style="margin: 2em;" rowKey="#{book.id}"><p:column headerText="Name"><h:outputText value="#{book.name}"/></p:column>
<p:column headerText="Year"><h:outputText value="#{book.year}"/></p:column>
<p:column headerText="Author"><h:outputText value="#{book.author}"/></p:column>
<p:column headerText="Category"><h:outputText value="#{book.category}"/></p:column>
<p:column headerText="Price"><h:outputText value="$#{book.price}"/></p:column>
<p:column style="width:100px;text-align: center"><p:commandButton icon="fa fa-pencil" update=":form:bookEdit" oncomplete="PF('editDialog').show()"><f:setPropertyActionListener value="#{book}" target="#{bookController.selectedBook}"/></p:commandButton><p:commandButton action="#{bookController.deleteBook(book)}" icon="fa fa-trash"></p:commandButton></p:column></p:dataTable>
<p:dialog header="Edit Book" widgetVar="editDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false"><p:outputPanel id="bookEdit" style="text-align:center;"><p:panelGrid columns="2" rendered="#{not empty bookController.selectedBook}" columnClasses="label,value">
<h:outputText value="Name: " /><p:inputText value="#{bookController.selectedBook.name}" />
<h:outputText value="Category: " /><p:inputText value="#{bookController.selectedBook.category}" />
<h:outputText value="Author: " /><p:inputText value="#{bookController.selectedBook.author}"/>
<h:outputText value="Price: $" /><p:inputText value="#{bookController.selectedBook.price}" />
<h:outputText value="Year: " /><p:inputText value="#{bookController.selectedBook.year}" /></p:panelGrid>
<p:commandButton value="Update" icon="fa fa-fw fa-pencil" action="#{bookController.updateBook()}"/></p:outputPanel></p:dialog></h:form></h:body></html>
At this stage, we are done building our CRUD app. So, let’s see what we are up to. Clean and build the app, deploy and run.
Let’s have a look at our view👀
The Create & Read parts (C & R)
Index page
We have an input form to create a new book then a datatable containing our books. The last column contains two buttons, to update and delete a book.
Let’s try inserting some data into our database from our view.
Datatable after adding new entity
The Update part (U)
To update an entity, click on the edit button, a modal will show up. From there, you can update the chosen entity
Update book modal
The Delete part (D)
Deleting can be done by clicking on the delete button which calls the corresponding function from our controller
public String deleteBook(Book book) {this.booksFacade.remove(book);return "index.xhtml?faces-redirect=true";}
We’ve reached the end of the tutorial. Now you are able to build your own J2EE with the various technologies mentionned above 🔥
For more assistance, drop me a mail at [email protected] or via direct message on my Twitter.
You can get the project from this Gitlab repository.
Made with ❤