jsf

JSF JPA CRUD Tutorial

Hello, in this tutorial I would like to show the usage of JPA (Java Persistence API’s) in a simple jsf application and will demonstrate the following:

  • Schools List
  • Performing database operations using JPA framework
  • Sending & retrieving data to & from a managed bean

This example will show the implementation of basic CRUD (Create, Read, Update, Delete) operations and lets you manage the school’s database in jsf using JPA with EclipseLink & MySQL.
 

1. Introduction

Java Persistence API (JPA), is a standard interface which wraps different Object Relational Mapping (ORM) tools such as Hibernate, EclipseLink, OpenJPA etc. By using JPA, we can do CRUD database operations (i.e. Create, Read, Update & Delete) with very little code.

We will have following components in this application:

  • schoolsList.xhtml – A jsf page displaying the school’s list
  • newSchool.xhtml – A jsf form page to add new school details in the database
  • schoolEdit.xhtml – A jsf form page to update the school details in the database
  • SchoolBean.java – Managed bean class for the school
  • SchoolEntityManager.java – Class that has all the getters & setters for the school table created in the database
  • DatabaseOperations.java – Class which is used to perform the database related operations using the JPA framework
  • persistence.xml – Configuration file containing database related information
  • web.xml – Web application configuration file

1.1 Java Persistence API (JPA)

JPA provides a javax.persistence.EntityManager interface which is used to interact with the database. The instance of EntityManager plays around the persistence context and EntityManagerFactory interacts with entity manager factory.

  1. Persistence context is the set of entity instances where for any persistence entity identity, there is a unique entity instance. The lifecycle of entity instances is managed within the persistence context using EntityManager. We can detach and merge the entity instances within a persistence context.
  2. EntityManager is a model borrowed from traditional JDBC frameworks, making it easy for the developers to perform the basic database operations (i.e. Create, Read, Update & Delete) with very little code.

In this standalone JPA example, we are using EclipseLink with MySQL Database. EclipseLink is a popular open source ORM (Object Relation Mapping) tool for Java platform used for mapping an entity to a traditional relational database like Oracle, MySQL etc.

Developers can check the below table for the different databases which are available with EclipseLink examples:

Database Driver class Jar name
MySQL com.mysql.jdbc.Driver mysql-connector-java-5.1.25-bin.jar (exact name depends on version)
http://www.mysql.com/downloads/connector/j/
HSQLDB org.hsqldb.jdbcDriver hsqldb.jar
http://hsqldb.sourceforge.net
Sybase com.sybase.jdbc3.jdbc.SybDriver jconnect.jar
http://www.sybase.com/products/allproductsa-z/softwaredeveloperkit/jconnect
Apache Derby org.apache.derby.jdbc.EmbeddedDriver derby.jar
http://db.apache.org/derby/
IBM DB2 com.ibm.db2.jcc.DB2Driver db2jcc4.jar
http://www-01.ibm.com/software/data/db2/linux-unix-windows/download.html
PostgreSQL org.postgresql.Driver postgresql-8.4-701.jdbc4.jar (exact name depends on PostgreSQL version)
http://jdbc.postgresql.org
SQL Server (Microsoft driver) com.microsoft.sqlserver.jdbc.SQLServerDriver sqljdbc4.jar
http://msdn.microsoft.com/en-gb/data/aa937724%28en-us%29.aspx

1.2 CRUD Operations

CRUD stands for Create, Read, Update and Delete. These functions are the user interfaces to databases, as they permit users to create, view, modify and alter data. CRUD works on entities in databases and manipulates these entities.

For instance, a simple student database table adds (creates) new student details, accesses (reads) existing student details, modifies (updates) existing student data, and deletes student details when students leave the school.

The commands corresponding to these operations in SQL are INSERT, SELECT, UPDATE and DELETE. INSERT adds new records, SELECT retrieves or selects existing records based on selection conditions, UPDATE modifies existing records and DELETE removes tables or records in a table.

1.3 JPA & CRUD Benefits

There are many advantages of using the JPA framework, for e.g.

  1. The benefit of using the JPA over any specific Object Relational Model (ORM) related libraries like Hibernate, iBatis etc. is that we need not change the code when we change the vendor
  2. The code is loosely coupled with the underlying ORM framework
  3. Improves data security and data access to users by using host and query languages
  4. Improves application performance by reducing the data redundancy
  5. Greater data integrity and independence of applications programs
  6. Provides simple querying of data

1.4 How it can be achieved?

Programmers can achieve persistence in their application by introducing persistence.xml in their code. This module plays a crucial role in the concept of JPA as in this configuration file we will register the database and specify the entity class. Let’s take a look and understand the sample code:

Sample persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
	xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
	<persistence-unit name="TestPersistence" transaction-type="RESOURCE_LOCAL">
		<class><!-- Entity Manager Class Name --></class>
		<properties>
			<property name="javax.persistence.jdbc.driver" value="Database Driver Name" />
			<property name="javax.persistence.jdbc.url" value="Database Url" />
			<property name="javax.persistence.jdbc.user" value="Database Username" />
			<property name="javax.persistence.jdbc.password" value="Database Password" />
		</properties>
	</persistence-unit>
</persistence>
Tip
It is mandatory to place persistence.xml in the project’s src/META-INF folder.

The persistence.xml file indicates that there is only one Persistence Unit mapped with the name TestPersistence and the transaction type for this Persistence Unit is RESOURCE_LOCAL. There are two types of transactions:

  • JTA
  • RESOURCE_LOCAL

If you select RESOURCE_LOCAL then the transaction will be managed by the JPA Provider Implementation in use. If JTA is specified, then the transactions will be managed by the Application Server.

Do remember, if a developer only wants to have JPA transactions, then RESOURCE_LOCAL is a good choice. But, if a developer would like the transactions to contain resources other than JPA, like EJBs, JMS then JTA is the correct choice.

Note: In this example, we are connecting the application with MySQL database. So, you must add the mysql-connector-java-<version>-bin.jar to the project.

1.5 Download & Install EclipseLink

You can watch this video in order to download and install the JPA in Eclipse via the EclipseLink.

1.6 Download and Install MySQL

You can watch this video in order to download and install the MySQL database on your Windows operations system.

2. JSF JPA Crud Tutorial

2.1 Tools Used

We are using Eclipse Kepler SR2, JDK 8 (1.8.0_131), Tomcat7 application server, MySQL database and MySQL connector jar. Having said that, we have tested the code against JDK 1.7 and it works well.

2.2 Project Structure

Firstly, let’s review the final project structure, in case you are confused about where you should create the corresponding files or folder later!

Fig. 1: JSF JPA Crud Application Project Structure
Fig. 1: JSF JPA Crud Application Project Structure

Tip
You may skip project creation and jump directly to the beginning of the example below.

2.3 Project Creation

This section will demonstrate on how to create a Dynamic Web Java project with Eclipse. In Eclipse IDE, go to File -> New -> Dynamic web project

Fig. 2: Create Dynamic Web Project
Fig. 2: Create Dynamic Web Project

In the New Dynamic Project window fill in the below details and click next

  • Enter the project name and project location
  • Select Target runtime as Apache Tomcat v7.0 from dropdown
  • Select Configuration as JavaServer Faces v.2.2 Project from dropdown (this is required to download the java server faces capabilities in your project)

Fig. 3: Project Details
Fig. 3: Project Details

Leave everything as default in this window as we will be making the required java file at a later stage. Simply click next and we will land up on the web-module window

Fig. 4: Java Src Window
Fig. 4: Java Src Window

In the Web Module window, leave the context_root and content_directory values as default (however, you can change the context_root but for the first application let’s keep it as a default value). Simply, check Generate web.xml deployment descriptor checkbox and click next

Fig. 5: Web Module Window
Fig. 5: Web Module Window

In the JSF Capabilities windows, we will require downloading the dependencies (not available by default) so that our project is configured as a JSF module in Eclipse. Add the JSF capabilities to the web project by clicking on the download icon (encircled in Fig. 6) and download the JSF 2.2 Mojarra implementation

Fig. 6: JSF Capabilities Window
Fig. 6: JSF Capabilities Window

A new pop-up window will open where it will auto lists down the JSF library. Select the JSF 2.2 library and click next (the library name and download destination will be auto populated)

Fig. 7: JSF Capabilities Download Window
Fig. 7: JSF Capabilities Download Window

Check the license checkbox and click finish. Eclipse will download the JSF 2.2 library and will display them on the JSF capabilities windows (i.e. Fig. 6)

Fig. 8: JSF Capabilities License Window
Fig. 8: JSF Capabilities License Window

Now the JSF implementation libraries will be listed down on the capabilities page. Select the checkbox (JSF2.2 (Mojarra 2.2.0)) and leave everything else as default. Click Finish

Fig. 9: JSF Capabilities Library Selection Window
Fig. 9: JSF Capabilities Library Selection Window

Eclipse will create the project named JSF JPA Crud in the workspace and web.xml will be configured for accepting the JSF requests. It will have the following code:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>JSF JPA Crud</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <context-param>
        <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
        <param-value>resources.application</param-value>
    </context-param>
    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>
</web-app>

2.4 JPA Configuration

Create a directory META-INF in src folder and create the file persistence.xml inside it. Add the following code to it:

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
	xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
	<persistence-unit name="JSFJPACrud">
		<class>com.jsf.jpa.crud.SchoolEntityManager</class>
		<!-- Configuring JDBC Connection -->
		<properties>
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/tutorialDb" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="" />
		</properties>
	</persistence-unit>
</persistence>

Note: We have kept the javax.persistence.jdbc.password value as blank for simplicity, however, it is pure unto user to keep it blank or set it during the MySQL configuration. If the user sets it, we need to provide the same password to this string.

2.5 Install MySQL Connector Jar

Download the MySQL-connection jar from here and copy in the project’s WEB-INF lib folder as per below image:

Fig. 10: MySQL Connector Jar
Fig. 10: MySQL Connector Jar

Let’s start building the application!

3. Application Building

Below are the steps involved in developing this application:

3.1 Database & Table Creation

This tutorial uses a database called tutorialDb. The database is not included when you create the project in eclipse so you need to first create the database to follow this tutorial:

  • Create a new database tutorialDb as:
CREATE DATABASE tutorialDb;
  • Use the created database tutorialDb to create table as:
USE tutorialDb;
  • Create the table school as shown below:
CREATE TABLE school (id INTEGER NOT NULL, name VARCHAR(120), PRIMARY KEY(id));
  • Now we shall insert some values into the school table as:
INSERT INTO school (id, name) VALUES (1, "Oxford. Sr. Sec. School");
INSERT INTO school (id, name) VALUES (2, "Kamal Public School");
INSERT INTO school (id, name) VALUES (3, "G.D. Goenka International School");
INSERT INTO school (id, name) VALUES (4, "DAV Public School");
INSERT INTO school (id, name) VALUES (5, "Ryan International School");
INSERT INTO school (id, name) VALUES (6, "Delhi Public School");
INSERT INTO school (id, name) VALUES (7, "Khaitan Public School");
  • View school table records as:
SELECT * FROM school;

If everything goes fine, the table and the records will be shown as below in the MySQL Workbench:

Fig. 11: Database and Table Creation
Fig. 11: Database and Table Creation

3.2 Source File Creation

For the demo, we are using a sample form application. Right click on project WebContent -> New -> File

Note: In JSF 2.0, it’s recommended to create a JSF page in xhtml format, a file format with .xhtml extension

Fig. 12: File Creation
Fig. 12: File Creation

A pop-up window will open. Verify the parent folder location as JSF JPA Crud/WebContent/WEB-INF and enter the file name as schoolsList.xhtml. Click Finish

Fig. 13: schoolsList.xhtml
Fig. 13: schoolsList.xhtml

Repeat the step where we need to create the file for our application (i.e. fig. 12). Again, verify the parent folder location as JSF JPA Crud/WebContent/WEB-INF and enter the filename newSchool.xhtml and click Finish

Fig. 14: newSchool.xhtml
Fig. 14: newSchool.xhtml

Again repeat the above step and enter the filename as schoolEdit.xhtml. Click Finish

Fig. 15: schoolEdit.xhtml
Fig. 15: schoolEdit.xhtml

3.2.1 Implementation of Source files

Here in schoolsList.xhtml we will have the jsf UI component’s displaying the school’s list, fetched directly from the school table at application loading. Here the bootstrap components will implement the CSS classes which we will enhance the application interface. The Add New School, Update and Delete buttons will display the corresponding results based on backend logic written. Add the following code to it:

schoolsList.xhtml

<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"  xmlns:h="http://java.sun.com/jsf/html"  xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
    <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1" http-equiv="X-UA-Conpatible" />
    <h:outputStylesheet library="css" name="bootstrap.min.css" />     
    <title>JSF JPA Crud Example</title>
    <style type="text/css">
        .tableUpdated {
        	width: 90% !important;
        	margin: 17px 58px 0 !important;
        }
        .btnSpace {
        	margin: 17px;
        }     
    </style>
</h:head>
<h:body>
    <center><h2><h:outputText value="School Records"/></h2></center>
    <h:form id="schoolForm">
        <h:dataTable id="schoolTable" binding="#{table}" value="#{schoolBean.schoolListFromDb()}" var="school" styleClass="table table-striped table-bordered tableUpdated">
            <h:column>
                <f:facet name="header">Id</f:facet>
                <h:outputText value="#{school.id}" />                
            </h:column>
            <h:column>
                <f:facet name="header">School Name</f:facet>
                <h:outputText value="#{school.name}" />
            </h:column>
            <h:column>
                <f:facet name="header">Update</f:facet>
                <h:commandButton action="#{schoolBean.editSchoolDetailsById()}" value="Update" styleClass="btn btn-primary">
                	<f:param name="selectedSchoolId" value="#{school.id}" />
                </h:commandButton>
            </h:column>
            <h:column>
                <f:facet name="header">Delete</f:facet>
                <h:commandButton action="#{schoolBean.deleteSchoolById(school.id)}" value="Delete" styleClass="btn btn-danger" />
            </h:column>
        </h:dataTable>
        <center><h:commandButton action="newSchool.xhtml?faces-redirect=true" value="Add New School" styleClass="btn btn-success btnSpace" /></center>
    </h:form>
</h:body>
</html>

Here in newSchool.xhtml we have a new school creation form wherein the new school details are entered. Upon clicking the Save button on this page, the new school record will be saved in the school table and will be displayed on the schools list page. Add the following code to it:

newSchool.xhtml

<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
    <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1" http-equiv="X-UA-Conpatible" />
    <h:outputStylesheet library="css" name="bootstrap.min.css" />
    <title>JSF JPA Crud Example</title>
    <style type="text/css">
        .btnWidth {
            width: 80px;
        }     
        .col-sm-updated {        	
    		padding-top: 7px;    		
        }
         .col-sm-updated a {
         	margin-left: 30px;
        	text-decoration: none !important;
        }
        .col-sm-27 {
        	width: 27% !important	;
        }
    </style>
</h:head>
<h:body>
	<center><h2><h:outputText value="Create School Record"/></h2></center>
    <h:form id="schoolBeanForm" styleClass="form-horizontal">        
      	<div class="form-group">
            <h:outputLabel for="id" styleClass="control-label col-sm-4">Id:</h:outputLabel>
            <div class="col-sm-4"><h:outputText value="Auto Selected By The System :)" styleClass="text text-success" /></div>
        </div>
        <div class="form-group">
            <h:outputLabel for="name" styleClass="control-label col-sm-4">Name:</h:outputLabel>
            <div class="col-sm-4">
                <h:inputText id="school-name" value="#{schoolBean.name}" styleClass="form-control" required="true" requiredMessage="School Name Cannot Be Blank" />
            </div>
            <h:message for="school-name" styleClass="text text-danger" />
        </div>        
        <div class="form-group">
            <div class="col-sm-2 col-sm-27" />
            <div class="col-sm-4">
                <div class="col-sm-2"><h:commandButton value="Save" action="#{schoolBean.addNewSchool(schoolBean)}" styleClass="btn btn-success btnWidth" /></div>
                <div class="col-sm-1" />
                <div class="col-sm-updated"><h:outputLink value="schoolsList.xhtml">View School Record List</h:outputLink></div>
            </div>
        </div>
    </h:form>
</h:body>
</html>

In schoolEdit.xhtml we will have the school id pre-fetched from the database for which the updating’s needs to be done. The user will update the values in this form and submit it. Add the following code to it:

schoolEdit.xhtml

<!DOCTYPE HTML>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"  xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:p="http://xmlns.jcp.org/jsf/passthrough">
<h:head>
    <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1" http-equiv="X-UA-Conpatible" />
    <h:outputStylesheet library="css" name="bootstrap.min.css" />
    <title>JSF JPA Crud Example</title>
    <style type="text/css">
        .updateBtnStyle {
        	width: 80px !important;        	
        }
         .col-sm-updated {        	
    		padding-top: 7px;    		
        }
         .col-sm-updated a {
         	text-decoration: none !important;
        }
        .text-edit {
        	margin-left: 123px !important;
    		margin-top: 29px !important;
        }
    </style>
</h:head>
<h:body>
	<center><h2><h:outputText value="Edit School Record"/></h2></center>
        <h:form id="editSchoolForm" styleClass="form-horizontal">                        
            <div class="form-group">
                <h:outputLabel for="idLabel" styleClass="control-label col-sm-2">Id:</h:outputLabel>
                <div class="col-sm-4"><h:inputText id="schoolId" value="#{schoolBean.editSchoolId}" p:readonly="readonly" styleClass="form-control" /></div>
            </div>
            <div class="form-group">
                <h:outputLabel for="nameLabel" styleClass="control-label col-sm-2">New Name:</h:outputLabel>
                <div class="col-sm-4"><h:inputText id="name" value="#{schoolBean.name}" styleClass="form-control" /></div>
            </div>
            <div class="form-group">
                <div class="col-sm-2" />
                <div class="col-sm-4">
                    <h:commandButton value="Update" action="#{schoolBean.updateSchoolDetails(schoolBean)}" styleClass="btn btn-primary updateBtnStyle" />
                </div>
                <div class="col-sm-1" />
                <div class="col-sm-updated"><h:outputLink value="schoolsList.xhtml">View School Record List</h:outputLink></div>
            </div>
            <div class="text text-success text-edit"><h:message for="schoolId" /></div>
        </h:form>
    </h:body>
</html>

3.3 Java Class Creation

Let’s create the required java files. Right click on src folder New -> Package

Fig. 16: Java Package Creation
Fig. 16: Java Package Creation

A new pop window will open where we will enter the package name as com.jsf.jpa.crud

Fig. 17: Java Package Name (com.jsf.jpa.crud)
Fig. 17: Java Package Name (com.jsf.jpa.crud)

Repeat the above step (i.e. Fig. 16) and enter the package name com.jsf.jpa.crud.db.operations

Fig. 18: Java Package Name (com.jsf.jpa.crud.db.operations)
Fig. 18: Java Package Name (com.jsf.jpa.crud.db.operations)

Once the packages are created in the application, we will need to create the required managed bean, entity-manager and database operations class. Right click on the newly create package New -> Class

Fig. 19: Java Class Creation
Fig. 19: Java Class Creation

A new pop window will open and enter the file name as SchoolBean. The bean class will be created inside the package – com.jsf.jpa.crud

Fig. 20: Java Class (SchoolBean.java)
Fig. 20: Java Class (SchoolBean.java)

Repeat the step (i.e. Fig. 19) and enter the filename as SchoolEntityManager. The JPA entity-manager class will be created inside the package – com.jsf.jpa.crud

Fig. 21: Java Class (SchoolEntityManager.java)
Fig. 21: Java Class (SchoolEntityManager.java)

Again, repeat the step listed in Fig. 19 and enter the file name as DatabaseOperations. The DAO class will be created inside the package – com.jsf.jpa.crud.db.operations

Fig. 22: Java Class (DatabaseOperations.java)
Fig. 22: Java Class (DatabaseOperations.java)

3.3.1 Implementation of Managed Bean Class

This class has methods which interact with action events clicked on the user interface pages and display the result on the output page based on the navigation logic returned from the DAO class. Add the following code to it:

SchoolBean.java

package com.jsf.jpa.crud;

import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;

import com.jsf.jpa.crud.db.operations.DatabaseOperations;

@ManagedBean
public class SchoolBean {

	private int id;
	private String name;	
	private String editSchoolId;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEditSchoolId() {
		return editSchoolId;
	}

	public void setEditSchoolId(String editSchoolId) {
		this.editSchoolId = editSchoolId;
	}

	// Method To Fetch The Existing School List From The Database
	public List schoolListFromDb() {
		return DatabaseOperations.getAllSchoolDetails();		
	}

	// Method To Add New School To The Database
	public String addNewSchool(SchoolBean schoolBean) {
		return DatabaseOperations.createNewSchool(schoolBean.getName());		
	}

	// Method To Delete The School Details From The Database
	public String deleteSchoolById(int schoolId) {		
		return DatabaseOperations.deleteSchoolDetails(schoolId);		
	}

	// Method To Navigate User To The Edit Details Page And Passing Selecting School Id Variable As A Hidden Value
	public String editSchoolDetailsById() {
		editSchoolId = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("selectedSchoolId");		
		return "schoolEdit.xhtml";
	}

	// Method To Update The School Details In The Database
	public String updateSchoolDetails(SchoolBean schoolBean) {
		return DatabaseOperations.updateSchoolDetails(Integer.parseInt(schoolBean.getEditSchoolId()), schoolBean.getName());		
	}
}

3.3.2 Implementation of EntityManager Class

This class has all the getters/setters for the school table. At the top this class, we tell the compiler that the table name is school. We declare the class an Entity by using the @Entity annotation and then we use the @Id annotation to generate an ID for the id column of the table. Add the following code to it:

SchoolEntityManager.java

package com.jsf.jpa.crud;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="school")
public class SchoolEntityManager {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;	
	private String name;

	public SchoolEntityManager() { }

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

3.3.3 Implementation of DAO Class

This class has methods which interacts with database for different operations i.e. creates a new school record, edit or update the existing school record or delete the record from the database. Add the following code to it:

DatabaseOperations

package com.jsf.jpa.crud.db.operations;

import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

import com.jsf.jpa.crud.SchoolBean;
import com.jsf.jpa.crud.SchoolEntityManager;

public class DatabaseOperations {

	private static final String PERSISTENCE_UNIT_NAME = "JSFJPACrud";	
	private static EntityManager entityMgrObj = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME).createEntityManager();
	private static EntityTransaction transactionObj = entityMgrObj.getTransaction();

	// Method To Fetch All School Details From The Database
	@SuppressWarnings("unchecked")
	public static List getAllSchoolDetails() {
		Query queryObj = entityMgrObj.createQuery("SELECT s FROM SchoolEntityManager s");
		List schoolList = queryObj.getResultList();
		if (schoolList != null && schoolList.size() > 0) {			
			return schoolList;
		} else {
			return null;
		}
	}

	// Method To Add Create School Details In The Database
	public static String createNewSchool(String name) {
		if(!transactionObj.isActive()) {
			transactionObj.begin();
		}

		SchoolEntityManager newSchoolObj = new SchoolEntityManager();
		newSchoolObj.setId(getMaxSchoolId());
		newSchoolObj.setName(name);
		entityMgrObj.persist(newSchoolObj);
		transactionObj.commit();
		return "schoolsList.xhtml?faces-redirect=true";	
	}

	// Method To Delete The Selected School Id From The Database 
	public static String deleteSchoolDetails(int schoolId) {
		if (!transactionObj.isActive()) {
			transactionObj.begin();
		}

		SchoolEntityManager deleteSchoolObj = new SchoolEntityManager();
		if(isSchoolIdPresent(schoolId)) {
			deleteSchoolObj.setId(schoolId);
			entityMgrObj.remove(entityMgrObj.merge(deleteSchoolObj));
		}		
		transactionObj.commit();
		return "schoolsList.xhtml?faces-redirect=true";
	}

	// Method To Update The School Details For A Particular School Id In The Database
	public static String updateSchoolDetails(int schoolId, String updatedSchoolName) {
		if (!transactionObj.isActive()) {
			transactionObj.begin();
		}

		if(isSchoolIdPresent(schoolId)) {
			Query queryObj = entityMgrObj.createQuery("UPDATE SchoolEntityManager s SET s.name=:name WHERE s.id= :id");			
			queryObj.setParameter("id", schoolId);
			queryObj.setParameter("name", updatedSchoolName);
			int updateCount = queryObj.executeUpdate();
			if(updateCount > 0) {
				System.out.println("Record For Id: " + schoolId + " Is Updated");
			}
		}
		transactionObj.commit();
		FacesContext.getCurrentInstance().addMessage("editSchoolForm:schoolId", new FacesMessage("School Record #" + schoolId + " Is Successfully Updated In Db"));
		return "schoolEdit.xhtml";
	}

	// Helper Method 1 - Fetch Maximum School Id From The Database
	private static int getMaxSchoolId() {
		int maxSchoolId = 1;
		Query queryObj = entityMgrObj.createQuery("SELECT MAX(s.id)+1 FROM SchoolEntityManager s");
		if(queryObj.getSingleResult() != null) {
			maxSchoolId = (Integer) queryObj.getSingleResult();
		}
		return maxSchoolId;
	}

	// Helper Method 2 - Fetch Particular School Details On The Basis Of School Id From The Database
	private static boolean isSchoolIdPresent(int schoolId) {
		boolean idResult = false;
		Query queryObj = entityMgrObj.createQuery("SELECT s FROM SchoolEntityManager s WHERE s.id = :id");
		queryObj.setParameter("id", schoolId);
		SchoolEntityManager selectedSchoolId = (SchoolEntityManager) queryObj.getSingleResult();
		if(selectedSchoolId != null) {
			idResult = true;
		}
		return idResult;
	}
}

4. Project Deploy

Once we are ready with all the changes done, let us compile and deploy the application on tomcat7 server. In order to deploy the application on tomcat7, right-click on the project and navigate to Run as -> Run on Server

Fig. 23: How to Deploy Application on Tomcat
Fig. 23: How to Deploy Application on Tomcat

Tomcat will deploy the application in its webapps folder and shall start its execution to deploy the project so that we can go ahead and test it on the browser.

Fig. 24: Tomcat Processing
Fig. 24: Tomcat Processing

Open your favorite browser and hit the following URL. The output page will be displayed.

http://localhost:8082/JSFJPACrud/faces/schoolsList.xhtml

Server name (localhost) and port (8085) may vary as per your tomcat configuration

5. Project Demo

Now, we are done with the application creation and its time to test out the application. Accessing the page: schoolsList.xhtml, we will see the page displaying the schools list.

Fig. 25: Schools List (Fetched from Db at application startup)
Fig. 25: Schools List (Fetched from Db at application startup)

Create New School Record: This page is used to add a new school record in student table.

Fig. 26: Create New School Form
Fig. 26: Create New School Form

Schools list page after adding a new record

Fig. 27: Schools List After Creation of New Student
Fig. 27: Schools List After Creation of New Student

Deleting a Student Record: Clicking on the delete button will remove the particular school from the student table. Let click on #8 button and see the result.

Fig. 28: #8 Record Deleted from the Database
Fig. 28: #8 Record Deleted from the Database

Update School Record: Clicking on the update button will navigate the user to the school edit form page. Here on this page, the particular school id will be pre-fetched on the page.

Fig. 29: Edit School Details Form
Fig. 29: Edit School Details Form

Submitting the form will update the details in the database and gives a success message on the page.

Fig. 30: Edit School Details Form – Success Message
Fig. 30: Edit School Details Form – Success Message

Hope this helped :)

6. Conclusion

Through this example, we learned about the JPA implementation in JSF. All the code for this example was deployed using the Tomcat7 application server.

7. Download the Eclipse Project

This was a JSF JPA Crud example with Eclipse, MySQL and Tomcat

Download
You can download the full source code of this example here: JSF JPA Crud

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

13 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Kunal Khandelwal
Kunal Khandelwal
6 years ago

Hello Yatin,

Thanks for this example. Please could you help me out with the following error which I am getting while running schoolsList.xhtml

Jan 18, 2018 5:37:20 PM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/schoolsList.xhtml]
javax.el.ELException: /schoolsList.xhtml @20,173 value=”#{schoolBean.schoolListFromDb()}”: java.lang.ExceptionInInitializerError
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)

Let me know in case you need the full error. Also when I remove the value tag from the schoolsList.xhtml for id=”schoolTable”, the page runs.

Marcin
Marcin
6 years ago

Hi, thanks for the tutorial. I’m trying to understand the concept of using persistence in JSF-applications, and this seems to be a nice way to start. However, I’m still struggling with getting the app to work. The error I’m getting is: Severe: Error Rendering View[/schoolsList.xhtml] javax.el.ELException: /schoolsList.xhtml @20,173 value=”#{schoolBean.schoolListFromDb()}”: java.lang.NoClassDefFoundError: Could not initialize class com.jsf.jpa.crud.db.operations.DatabaseOperations at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114) which let me wonder, where does the class DatabaseOperations get instantiated? Or maybe you have some other tips? I’d be really grateful for help. I must also add, I implemented the whole solution in Netbeans, hope there are no major differences. Kind regards,… Read more »

Marcin
Marcin
6 years ago
Reply to  Yatin

I recently realized the problem begins even earlier. The application doesn’t even get deployed. I’m getting:

The module has not been deployed.
See the server log for details.

The problem is, Glassfish doesn’t tell much:
Info: Initializing Mojarra 2.2.12 ( 20150720-0848 https://svn.java.net/svn/mojarra~svn/tags/2.2.12@14885) for context ‘/JSFJPACrud’
Info: Loading application [JSFJPACrud] at [/JSFJPACrud]
Severe:

So, there is a severe error, but no additional info. My persistence.xml looks like this:

com.jsf.jpa.crud.SchoolEntityManager

<!—->

I’d be grateful for any hints.

Marcin
Marcin
6 years ago
Reply to  Yatin

Hi, seems that I messed up with the JNDI-Connection together with persistence.xml. As I’m using JNDI, it was enough to define the core of persistence.xml to use JNDI (I’m unfortunately not able to paste it here, as xml content gets malformed in comment fields).

But yes, the mysql library was also missing. All in all everything works with Netbeans / Glassfish as well, thanks a lot!

Regards,
Marcin

Reginaldo
Reginaldo
5 years ago

Hi! I’m getting the following error:

Type Exception Report

Message Method not found: class com.jsf.jpa.crud.SchoolBean.schoolListFromDb()

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

javax.servlet.ServletException: Method not found: class com.jsf.jpa.crud.SchoolBean.schoolListFromDb()
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Could you help me out?
Thanks!!

humberto Mariano
humberto Mariano
4 years ago

Type Exception Report

Message java.lang.NoClassDefFoundError: Could not initialize class com.jsf.jpa.crud.db.operations.DatabaseOperations

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

javax.servlet.ServletException: java.lang.NoClassDefFoundError: Could not initialize class com.jsf.jpa.crud.db.operations.DatabaseOperations
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause

javax.faces.el.EvaluationException: java.lang.NoClassDefFoundError: Could not initialize class com.jsf.jpa.crud.db.operations.DatabaseOperations
javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
javax.faces.component.UICommand.broadcast(UICommand.java:315)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause

java.lang.NoClassDefFoundError: Could not initialize class com.jsf.jpa.crud.db.operations.DatabaseOperations
com.jsf.jpa.crud.SchoolBean.addNewSchool(SchoolBean.java:59)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.apache.el.parser.AstValue.invoke(AstValue.java:247)
org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:267)
com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
javax.faces.component.UICommand.broadcast(UICommand.java:315)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note A pilha de erros completa da causa principal está disponível nos logs do servidor.[

Miguel Angel Calderon Martin
Miguel Angel Calderon Martin
4 years ago

The commandButton

Dont work:

Error 500: javax.servlet.ServletException: /newSchool.xhtml at line 40 and column 157 action=”#{schoolBean.addNewSchool(schoolBean)}”: Method not found: com.jsf.jpa.crud.SchoolBean@80d873a.addNewSchool(com.jsf.jpa.crud.SchoolBean)

swakopmund
swakopmund
1 year ago

On returning to the schoolList.xhtml, the old school name is displayed. How do you display the new school name, instead of the old school name ??

Back to top button