Friday, November 10, 2017

CRUD Operation Using Hibernate

What is Hibernate: Database interaction always being a cumbersome process for a developer. With JDBC database interaction is quite complex, time consuming and inconvenience. Hibernate is a tool or an API that solve lot of the problems of developers related to database. I am not saying that JDBC is not a good choice, of course it is. JDBC provides relatively fast access than hibernate. Hibernate is a abstraction and abstraction is always slow process. But it enable developer fast development and object oriented environment. With JDBC developer need to have a strong understanding of sql and database. But hibernate does not require expertise in SQL and database. A Developer which have little knowledge (or may be not) can play with database because he has to work with class objects only. Every good thins need some sacrifice and hibernate is good thing so it need some execution speed as sacrifice.
Hibernate is an ORM(Object Relational Mapping) tool, That maps your persistence java entity/class to table directly and instances are mapped to rows and attributes of instances are mapped to columns of table.
I am writing this post to not make you hibernate expert but only provide some basic idea and how you can start learning this. Lets start with a simple CRUD operations. I’ll explain things when it needed.
Step1: For starting hibernate you will need following jar files
dom4j.jar
slf4j-log4j12-1.6.6.jar
hibernate-core-3.3.2.GA.jar
cglib-2.2.jar
slf4j-api-1.6.6.jar
log4j-1.2.15.jar
mysql-connector-java-5.1.9.jar//Its depends which database you are using
commons-logging-1.0.4.jar
commons-collections-3.1.jar
javassist-3.12.1.GA.jar
jta-1.1.jar
antlr-2.7.6.jar
Download these jar files and put them build path of your application.
Now you have jar files so you can start developing hibernate application.
Step2. Configure you hibernate environment:
Create a configuration file named hibernate.cfg.xml. and keep this file in your source folder(class path).
<?xml version=”1.0″ encoding=”utf-8″?>
<!DOCTYPE hibernate-configuration PUBLIC
“-//Hibernate/Hibernate Configuration DTD 3.0//EN”
http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”&gt;
<hibernate-configuration>
<session-factory>
<property name=”hibernate.dialect”>
org.hibernate.dialect.MySQLDialect (change it according to your database)
</property>
<property name=”hibernate.connection.driver_class”>
com.mysql.jdbc.Driver(change it according to your database)
</property>
<!– database name is crud –>
<property name=”hibernate.connection.url”>
jdbc:mysql://localhost/crud(change it according to your database)
</property>
<property name=”hibernate.connection.username”>
root(change it according to your database)
</property>
<property name=”hibernate.connection.password”>
root(change it according to your database)
</property>
<property name=”hibernate.hbm2ddl.auto”>
update
</property>
<!– List of XML mapping files that have you entities maping for persistance –>
<mapping resource=”Student.hbm.xml” />(change it according to your entity class)
</session-factory>
</hibernate-configuration>
The first thing you have to notice in this file is DOCTYPE you can find doctype for your hibernate version in /org/hibernate/hibernate-configuration-3.0.dtd file inside hibernate-core jar. Please make sure your doctype should match doctype define in /org/hibernate/hibernate-configuration-3.0.dtd, otherwise you should be ready to face exception says hibernate.cfg.xml can not be parsed. Hibernate configuration file contains some properties an their value like dialect, driver_class, url, username, password etc. Hibernate uses these properties to make Session factory for you database. Hibernate supports all major databases. There is one another property I used here  hbm2ddl.auto. This is used to create/update databse table and fields if they do not exists. You can use its value “create” instead of “update” but it will delete your data each time you run application. Besides all these things it contains list of mapping files for all persistence entities that you want to persist in database. Here I provided mapping file for Student entity.
Your project structure should similar to shown below here.
hibernateBeginersfolderstructure.png
Step3. Create POJO java class that you want to persist:
Create a POJO class that you want to save in database. Always keep in mind that your persistent entity should have default constructor. If you are using parameterized constructor in persistent entity you have to define a default constructor, besides that you have to define a discriminatory property says id. This id field is used by hibernate to distinguish rows in database table . Lets have an example entity Student.
public class Student {
private String firstName;
private String lastName;
private String studentClass;
private int rollNumber;
private int id;

public Student() {
}

public Student(String firstName, String lastName, String studentClass,
int rollNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.studentClass = studentClass;
this.rollNumber = rollNumber;
}

//setter and getter for all properties
}
Its mandatory to define getter-setter for all properties.
Step4: Create mapping file: 
For all your entities you want to persistent you would need to define a mapping file(If you are not using annotations). This mapping file contains mapping of your class properties with table’s fields.
Your mapping file name should be like {EntityName}.hbm.xml.Stduent.hbm.xml content is: 
<?xml version=”1.0″ encoding=”utf-8″?>
<!DOCTYPE hibernate-mapping PUBLIC 
    “-//Hibernate/Hibernate Mapping DTD 3.0//EN”
    “http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd”&gt;
<hibernate-mapping>
<class name=”com.kd.example.models.Student” table=”STUDENT”>
<id name=”id” type=”java.lang.Integer” column=”ID”>
<generator class=”native” />
</id>
<property name=”firstName” type=”java.lang.String” column=”FIRST_NAME” />
<property name=”lastName” type=”java.lang.String” column=”LAST_NAME” />
<property name=”studentClass” type=”java.lang.String” column=”STUDENT_CLASS” />
<property name=”rollNumber” type=”java.lang.Integer” column=”ROLL_NAME” />
</class>
</hibernate-mapping>
I think its content is self explanatory. One thing that i want to mention here is generator. Generator is a mechanism used by hibernate to create id field value. Hibernate provides many classes for this purpose.
Step5: Now you have configure all necessary environment for  hibernate so you can start interacting with database.
Here I am presenting you an simple main class that demonstrate create, update delete and listing.
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.kd.example.models.Student;
import com.kd.example.utils.HibernateUtils;
public class RunCRUDOperations {
public static SessionFactory sessionFactory = HibernateUtils.getSessionFactory();
public static void main(String[] args) {
createStudent();
System.out.println(“List All Rows exist in database table after create: “);
System.out.println(“==============================================”);
listStudents();
updateStudent();
System.out.println(“List All Rows exist in database table after update: “);
System.out.println(“==============================================”);
listStudents();
deleteStudent();
System.out.println(“List All Rows exist in database table after delete: “);
System.out.println(“==============================================”);
listStudents();
}
private static void createStudent() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Student student1 = new Student(“Kuldeep”, “Singh”, “A”, 123);
Student student2 = new Student(“Rahul”, “Kumar”, “AB”, 1234);
Student student3 = new Student(“Tarun”, “Desai”, “ABC”, 1235);
Student student4 = new Student(“Amit”, “Rai”, “ABC”, 1236);
Student student5 = new Student(“Sachin”, “Sharma”, “XYZ”, 1237);
Student student6 = new Student(“Mahednra”, “Singh”, “A”, 1238);
session.save(student1);
session.save(student2);
session.save(student3);
session.save(student4);
session.save(student5);
session.save(student6);
tx.commit();
session.close();
}
private static void updateStudent() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Student student = (Student) session.get(Student.class, 1);
// update class
student.setStudentClass(“XYZ”);
                session.save(student);
                tx.commit();
session.close();
}
private static void listStudents() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery(“from Student”);
@SuppressWarnings(“unchecked”)
List<Student> students = query.list();
for (Student student : students) {
System.out.println(“First Name: ” + student.getFirstName()
+ ” Last Name: ” + student.getLastName()
+ ” Student Class: ” + student.getStudentClass()
+ ” Roll Number: ” + student.getRollNumber());
}
tx.commit();
session.close();
}
        private static void deleteStudent() {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.delete((Student) session.get(Student.class, 6));
tx.commit();
session.close();
}
}
Step6: Create a util class which is used to return an Session Factory object.
package com.kd.example.utils;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class HibernateUtils {
public static SessionFactory getSessionFactory() {
//build session factory from meta date you provided in hibernate.cfg.xml
SessionFactory factory = null;
try {
factory =new Configuration().configure().buildSessionFactory();
} catch (Exception e) {
System.out.println(“something went wrong session factory not created”);
e.printStackTrace();
}
return factory;
}
}
If you run above example output will be look like this:
List All Rows exist in database table after create: 
========================================================
First Name: Kuldeep Last Name: Singh Student Class: A Roll Number: 123
First Name: Rahul Last Name: Kumar Student Class: AB Roll Number: 1234
First Name: Tarun Last Name: Desai Student Class: ABC Roll Number: 1235
First Name: Amit Last Name: Rai Student Class: ABC Roll Number: 1236
First Name: Sachin Last Name: Sharma Student Class: XYZ Roll Number: 1237
First Name: Mahednra Last Name: Singh Student Class: A Roll Number: 1238

List All Rows exist in database table after update: 
========================================================
First Name: Kuldeep Last Name: Singh Student Class: XYZ Roll Number: 123
First Name: Rahul Last Name: Kumar Student Class: AB Roll Number: 1234
First Name: Tarun Last Name: Desai Student Class: ABC Roll Number: 1235
First Name: Amit Last Name: Rai Student Class: ABC Roll Number: 1236
First Name: Sachin Last Name: Sharma Student Class: XYZ Roll Number: 1237
First Name: Mahednra Last Name: Singh Student Class: A Roll Number: 1238

List All Rows exist in database table after delete: 
========================================================
First Name: Kuldeep Last Name: Singh Student Class: XYZ Roll Number: 123
First Name: Rahul Last Name: Kumar Student Class: AB Roll Number: 1234
First Name: Tarun Last Name: Desai Student Class: ABC Roll Number: 1235
First Name: Amit Last Name: Rai Student Class: ABC Roll Number: 1236
First Name: Sachin Last Name: Sharma Student Class: XYZ Roll Number: 1237
Now you may want some explanation on SessionFactory, Session, and Transaction. Let me explain these in brief.
SessionFactory:  SessionFactory is an interface, whose implementation is provided by hibernate itself. This is the object which provides environment and resources to connect to database on the basis of your configuration files. SessionFactory is thread safe, and heavy weight object. So we should avoid making unnecessary SessionFactory object. One SessionFactory object is created for a database. And we should create single SessionFactory object for a single application but you are using multiple databases in your application you can create multiple SessionFactory objects.  Usually SessionFactory is used to get Session object.
Session: Session object represents physical database connection. If you open a session, you are connected to database and can perform database related tasks. Session is not thread safe, so need extra care while using in multithreading environment. Session is light weight object so it should be open
each time you want to interact with database and close when you finished with the task.
Transaction: Transaction object represents an atomic unit to work.This is light weight and not thread safe.Transaction object is created under Session scope and closed before closing Session. A single Session can have multiple Transaction objects.
An object of persistence entity can be in three states:-
Transient Object: An object of persistence entity that is not associated with hibernate session, and does not have any identifier in database attached to the object., is called Transient object.
Persistence Object:  An object persistence entity that is associated with a hibernate session and have identifier in database, is called Persistence Object.
Detached Object: An object of persistence entity that is not associated with hibernate session but have identifier in database, is called Detached Object.

0 comments:

Post a Comment