Monday, 3 February 2014

CRUD Application in Netbeans using EJB and JPA with MySQL



This tutorial demonstrates how to make an EJB application in Netbeans using JPA and the database as MYSQL.
This is an example of using CRUD (create, retrieve, update and delete) operations using JPA and MySQL database that follows the MVC architecture. It includes a login page which allows only registered users to login and a home page which has the CRUD features to add, edit, delete and search students from the database.

Before we start with the application we need the following:

Step 1: Create a database called 'mydatabase' using the MySQL workbench and create two tables called 'login' (which will store the usernames and passwords of users who can log in) and 'student' (which will store the details of students) and insert some data into the tables.

Login table


Student table



Step 2: Create a new Java Web Application project  and give any name such as 'MyEJBApplication' and select the server as 'Glassfish' (Mostly everything would be present by default)





Step 3: Create a JDBC Connection Pool (Right click on Project name -> New -> Other -> Glassfish(folder) -> JDBC Connection Pool) 


Step 4: Select MySQL from the dropdown box as shown below. ( Note the name of the connection pool) - in this case it is 'connectionPool')






















Step 5: Provide the host, port (within the URL parameter), username and password of your mysql database as shown below:




Step 6: Create a JDBC Resource (Right click on Project name -> New -> Other -> Glassfish(folder) -> JDBC Resource).




Step 7: Select the JDBC connection pool name you just in created above (step 4) from the drop down box. Provide a JNDI name as shown:



























Step 8: Create a Persistence Unit (Right click on Project name -> New -> Other -> Persistence -> Persistence Unit).



Step 9:  Provide a name to the Persistence Unit and select the data source name which you gave while creating the JDBC Resource above (step 7). (Note that the table generation strategy is set to 'None')



Step 10: Create 3 JSP Pages namely home.jsp, login.jsp and error.jsp and insert the following codes respectively

home.jsp

<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Welcome <%=session.getAttribute("loginName")%> </h1>
<h1>Student Information</h1>
<form action="./StudentServlet" method="POST">
<table>
<tr>
<td>Student ID</td>
<td><input type="text" name="studentId" value="${student.studentId}" /></td>
</tr>
<tr>
<td>First Name</td>
<td><input type="text" name="firstname" value="${student.firstName}" /></td>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="lastname" value="${student.lastName}" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" name="action" value="Add" />
<input type="submit" name="action" value="Edit" />
<input type="submit" name="action" value="Delete" />
<input type="submit" name="action" value="Search" />
</td>
</tr>
</table>
</form>
<br>
<table border="1">
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<s:forEach items="${allStudents}" var="stud">
<tr>
<td>${stud.studentId}</td>
<td>${stud.firstName}</td>
<td>${stud.lastName}</td>
</tr>
</s:forEach>
</table>
</body>
</html>
view raw home.jsp hosted with ❤ by GitHub


login.jsp

<%@page pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<body >
<form method="POST" action="/EJBApplication/LoginServlet">
<table border="0">
<tr>
<td>Username</td>
<td><input type="text" name="userName"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password"></td>
</tr>
<tr><td colspan="2" align="center">
<input type="submit" value="Login"></td>
</tr>
</table>
</form>
</body>
</html>
view raw login.jsp hosted with ❤ by GitHub


error.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Error - <%=request.getAttribute("error")%> </h1>
</body>
</html>
view raw error.jsp hosted with ❤ by GitHub



Step 11: Create 3 packages as follows:

Step 11.1: First package com.model and create 2 Entity beans namely 'Login' and 'Student' and insert the following codes respectively.

com.model.Login.java

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity
@Table
@NamedQueries({@NamedQuery(name="Login.getAll",query="SELECT e FROM Login e")})
public class Login implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column
private int userId;
@Column
private String userName;
@Column
private String password;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
view raw Login.java hosted with ❤ by GitHub


com.model.Student.java

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
@Entity
@Table
@NamedQueries({@NamedQuery(name="Student.getAll",query="SELECT e FROM Student e order by e.studentId")})
public class Student implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column
private int studentId;
@Column
private String firstName;
@Column
private String lastName;
public Student(int studentId, String firstName, String lastName) {
this.studentId = studentId;
this.firstName = firstName;
this.lastName = lastName;
}
public Student() {
}
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
view raw Student.java hosted with ❤ by GitHub


Step 11.2: Second package com.dao that contains the Session Beans (create by right click on project name -> New -> Session Bean) namely 'LoginDAO' and 'StudentDAO'. ( Both these session beans implement methods from a local interface. Select the 'Local Interface'option while creating the session beans. The LoginDAOLocal and StudentDAOLocal will be automatically created). Add the following respective codes to the session beans and their interfaces appropriately. 

com.dao.LoginDAO

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.dao;
import com.model.Login;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
/**
*
* @author Vedang Rane
*/
@Stateless
public class LoginDAO implements LoginDAOLocal {
@PersistenceContext
private EntityManager em;
@Override
public boolean checkUser(String userName, String password) {
List<Login> s = (List<Login>)em.createQuery("select e from Login e where e.userName='"+userName+"' and e.password='"+password+"'").getResultList();
System.out.println("is list empty ?"+s.isEmpty()+" for the"+userName+" and "+password);
if(!s.isEmpty())
return true;
else
return false;
}
// Add business logic below. (Right-click in editor and choose
// "Insert Code > Add Business Method")
}
view raw LoginDAO.java hosted with ❤ by GitHub


com.dao.LoginDAOLocal

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.dao;
import com.model.Login;
import javax.ejb.Local;
/**
*
* @author Vedang Rane
*/
@Local
public interface LoginDAOLocal {
public boolean checkUser(String username, String password);
}


com.dao.StudentDAO

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.dao;
import com.model.Student;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
/**
*
* @author Joseph
*/
@Stateless
public class StudentDAO implements StudentDAOLocal {
@PersistenceContext
private EntityManager em;
@Override
public void addStudent(Student student) {
em.merge(student);
em.flush();
}
@Override
public void editStudent(Student student) {
em.merge(student);
em.flush();
}
@Override
public void deleteStudent(int studentId) {
em.remove(getStudent(studentId));
em.flush();
}
@Override
public Student getStudent(int studentId) {
em.flush();
return em.find(Student.class, studentId);
}
@Override
public List<Student> getAllStudents() {
em.flush();
return em.createNamedQuery("Student.getAll").getResultList();
}
}
view raw StudentDAO.java hosted with ❤ by GitHub


com.dao.StudentDAOLocal

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.dao;
import com.model.Student;
import java.util.List;
import javax.ejb.Local;
/**
*
* @author Joseph
*/
@Local
public interface StudentDAOLocal {
void addStudent(Student student);
void editStudent(Student student);
void deleteStudent(int studentId);
Student getStudent(int studentId);
List<Student> getAllStudents();
}


Step 11.3: Third package com.controller that contains the servlets namely 'LoginServlet' and 'StudentServlet' and add the following codes respectively.

com.controller.LoginServlet

package com.controller;
import com.dao.LoginDAOLocal;
import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
* @author Vedang Rane
*/
public class LoginServlet extends HttpServlet {
@EJB
private LoginDAOLocal loginDao;
Boolean check=false;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String userName = request.getParameter("userName");
String password = request.getParameter("password");
HttpSession session = request.getSession();
check = loginDao.checkUser(userName,password);
System.out.println("check is"+check+" "+userName);
if(check)
{
session.setAttribute("loginName", userName);
request.getRequestDispatcher("home.jsp").forward(request, response);
}
else
{
request.setAttribute("error", "Wrong Username or Password");
request.getRequestDispatcher("error.jsp").forward(request, response);
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
com.controller.StudentServlet

package com.controller;
import com.dao.StudentDAOLocal;
import com.model.Student;
import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Joseph
*/
@WebServlet(name = "StudentServlet")
public class StudentServlet extends HttpServlet {
@EJB
private StudentDAOLocal studentDao;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("action");
String studentIdStr = request.getParameter("studentId");
int studentId=0;
if(studentIdStr!=null && !studentIdStr.equals("")){
studentId=Integer.parseInt(studentIdStr);
}
String firstname = request.getParameter("firstname");
String lastname = request.getParameter("lastname");
Student student = new Student(studentId, firstname, lastname);
if("Add".equalsIgnoreCase(action)){
studentDao.addStudent(student);
}else if("Edit".equalsIgnoreCase(action)){
studentDao.editStudent(student);
}else if("Delete".equalsIgnoreCase(action)){
studentDao.deleteStudent(studentId);
}else if("Search".equalsIgnoreCase(action)){
student = studentDao.getStudent(studentId);
}
request.setAttribute("student", student);
request.setAttribute("allStudents", studentDao.getAllStudents());
request.getRequestDispatcher("home.jsp").forward(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}

Step 12: Check your configuration files(web.xml, persistence.xml and glassfish-resources.xml). They should be as follows:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>StudentServlet</servlet-name>
<servlet-class>com.controller.StudentServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.controller.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentServlet</servlet-name>
<url-pattern>/StudentServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
view raw web.xml hosted with ❤ by GitHub
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="EJBApplicationPU" transaction-type="JTA">
<jta-data-source>jdbc/myEJBApplicationREsource</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
view raw persistence.xml hosted with ❤ by GitHub
glassfish-resources.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
<jdbc-resource enabled="true" jndi-name="jdbc/myEJBApplicationREsource" object-type="user" pool-name="connectionPool">
<description/>
</jdbc-resource>
<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="connectionPool" non-transactional-connections="false" ping="false" pool-resize-quantity="2" pooling="true" res-type="javax.sql.DataSource" statement-cache-size="0" statement-leak-reclaim="false" statement-leak-timeout-in-seconds="0" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
<property name="URL" value="jdbc:mysql://localhost:3306/mydatabase"/>
<property name="User" value="root"/>
<property name="Password" value="vedang123"/>
</jdbc-connection-pool>
</resources>

Step 13: The final directory structure of the entire project should look as follows:


Step 14: Run the application by Right click on the project name -> Run

14.a: You should see login.jsp. Provide the username as 'admin' and password as 'admin' (as given in the login table in mydatabase) and click on Login.



14.b: You can now add, edit, delete or search for student records from the student table.





Notes:
  • The Java Persistence API (JPA) is one possible approach to ORM. JPA is a specification and several implementations are available. Popular implementations are Hibernate, EclipseLink and Apache OpenJPA. (You can check the implementation while creating the persistence.xml configuration file. In this case or by default in netbeans its EclipseLink).
  • The Entity beans represent the data in the database. Each instance of an entity bean corresponds to a row in the table. Session beans contain the actual business logic methods.




11 comments:

  1. hello, i have that problem:
    In-place deployment at C:\Users\Camue\Documents\NetBeansProjects\MyEJBApplication\build\web
    GlassFish Server 4.1, deploy, null, false
    C:\Users\Camue\Documents\NetBeansProjects\MyEJBApplication\nbproject\build-impl.xml:1045: The module has not been deployed.
    See the server log for details.
    BUILD FAILED (total time: 6 seconds)

    please help

    ReplyDelete
    Replies
    1. In this case just check the glassfish server log for the exact error. The log is located at

      {Your_GlassFish_Location}\glassfish\domains\domain1\logs\server.log

      Just a guess - The reason could be a missing jar file.

      Delete
  2. Where can download this entire project?
    Please could make available for download?
    thank you

    ReplyDelete
  3. Could you please send a project for me??
    fer.elias1@gmail.com

    ReplyDelete
  4. hello I need Your help please ! Ihave this error :
    Starting GlassFish Server 4.1.1
    GlassFish Server 4.1.1 is running.
    In-place deployment at C:\Users\user\Desktop\khadidja\AKHER_AMAL\AKHER_AMAL-war\build\web
    GlassFish Server 4.1.1, deploy, null, false
    C:\Users\user\Desktop\khadidja\AKHER_AMAL\AKHER_AMAL-war\nbproject\build-impl.xml:1076: The module has not been deployed.
    See the server log for details.
    BUILD FAILED (total time: 1 minute 20 seconds)

    ReplyDelete
  5. thanks bro. But after entering username an password to login I get an error which says "The server encountered an internal error that prevented it from fulfilling this request." what do I do?

    ReplyDelete
    Replies
    1. the same error like me, how to solve this problem?

      Delete
  6. Do you have full source code on github ?

    ReplyDelete