Agenda
Agenda (Cont.)
What is Hibernate?
The Problem solved by hibernate
User Class |
---|
Id |
Name |
Address |
Phone |
Date of Birth |
Id | Name | Address | Phone | Date of Birth |
---|---|---|---|---|
The Problem solved by hibernate (Cont.)
Set up with gradle
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
compile('org.hibernate:hibernate-core:5.2.6.Final')
compile ('mysql:mysql-connector-java:5.1.6')
}
<?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">
<hibernate-configuration>
<session-factory>
<!--Database connection settings -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/poc</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"/>
<!--JDBC connection pool-->
<property name="connection.pool_size">10</property>
<!-- SQL Dialect-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!--echo all executed SQL-->
<property name="show_sql">true</property>
<!--drop or re-create database schema at startup-->
<property name="hbm2ddl.auto">create</property>
<!--Annotated entity class-->
<mapping class="com.hibernate.demo.Person"/>
</session-factory>
</hibernate-configuration>
hibernate.cfg.xml
hbm2ddl configurations
Special note about update for hbm2ddl auto
update won't modify existing table column definitions.
update will add a db column that doesn't already exist.
update will not delete a db column that is removed/no longer in your entity.
update will not modify a db column that has already been created.
@Id and @Entity
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
Integer id;
String name;
Integer age;
}
CRUD (Create)
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Application {
public static void main(String[] args) {
Person person=new Person();
person.setName("Hibernate");
person.setAge(27);
person.setId(2);
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
}
}
CRUD (Read)
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Application {
public static void main(String[] args) {
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
Person person=session.get(Person.class,1);
session.getTransaction().commit();
session.close();
System.out.println(person);
}
}
CRUD (Update)
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Application {
public static void main(String[] args) {
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
Person person=session.get(Person.class,1);
person.setName("Updated Name");
session.update(person);
session.getTransaction().commit();
session.close();
System.out.println(person);
}
}
CRUD (Delete)
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Application {
public static void main(String[] args) {
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
Person person=session.get(Person.class,1);
session.delete(person);
session.getTransaction().commit();
session.close();
System.out.println(person);
}
}
Transient, Persistent and Detached states
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Application {
public static void main(String[] args) {
Person person=new Person();
//Transient state
person.setName("Hibernate");
person.setAge(23);
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
//Persistent state
session.save(person);
person.setName("Updated");
session.getTransaction().commit();
session.close();
sessionFactory.close();
//Detached state
person.setName("Updated in detached");
}
}
Name Annotations
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity(name = "Employee")
public class Person {
@Id
Integer id;
@Column(name = "First_Name")
String name;
Integer age;
}
More Annotations
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "Employee")
public class Person {
@Id
Integer id;
@Column(name = "First_Name")
String name;
@Transient
Integer age;
@Temporal(TemporalType.DATE)
Date dob;
}
Automatically generate primary key value
@Entity
@Table(name = "Employee")
public class Person {
@Id @GeneratedValue(strategy =GenerationType.SEQUENCE )
Integer id;
String name;
Integer age;
@Temporal(TemporalType.DATE)
Date dob;
}
IDENTITY: Tells Doctrine to use special identity columns in the database that generate a value on insertion of a row. This strategy does currently not provide full portability and is supported by the following platforms:
MySQL/SQLite => AUTO_INCREMENT
MSSQL => IDENTITY
PostgreSQL => SERIAL
Id Generation Stratergies
Id Generation Stratergies (cont.)
Embedded Type
import javax.persistence.*;
@Entity
public class Person{
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
String name;
Integer age;
@Embedded
Address address;
}
For embedded object we can use @Embedded annotation for the Reference type instance variable
import javax.persistence.Embeddable;
@Embeddable
public class Address {
String city;
String country;
}
Optionally we can also place @Embeddable on the class of the reference type instance variable
Embedded type (Cont.)
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Application {
public static void main(String[] args) {
Person person=new Person();
person.setName("Hibernate");
person.setAge(23);
Address address=new Address();
address.setCity("Delhi");
address.setCountry("India");
person.setAddress(address);
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
session.close();
}
}
Saving Collections
import javax.persistence.*;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
@Entity
@Table(name = "Employee")
public class Person {
@Id @GeneratedValue(strategy =GenerationType.SEQUENCE )
Integer id;
String name;
Integer age;
@Temporal(TemporalType.DATE)
Date dob;
@ElementCollection
Set<String> hobbies=new HashSet<String>();
}
One to One mapping
import javax.persistence.*;
@Entity
@Table(name = "Employee")
public class Person {
@Id @GeneratedValue(strategy =GenerationType.SEQUENCE )
Integer id;
String name;
Integer age;
@OneToOne
@JoinColumn(name = "Vehicle_join_column")
Vehicle vehicle;
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Vehicle {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
Integer vehicleId;
String vehicleName;
}
One to One mapping (Cont.)
Person person=new Person();
person.setName("Hibernate");
person.setAge(27);
person.setId(1);
Vehicle vehicle=new Vehicle();
vehicle.setVehicleName("Car");
person.setVehicle(vehicle);
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
session.save(person);
session.save(vehicle);
session.getTransaction().commit();
session.close();
One to Many (Unidirectional)
import javax.persistence.*;
import java.util.Collection;
import java.util.HashSet;
@Entity
@Table(name = "Employee")
public class Person {
@Id @GeneratedValue(strategy =GenerationType.SEQUENCE )
Integer id;
String name;
Integer age;
@OneToMany
@JoinTable(joinColumns = @JoinColumn(name="USER_ID")
,inverseJoinColumns = @JoinColumn(name = "VEHICAL_ID"))
Collection<Vehicle> vehicle= new HashSet<Vehicle>();
}
import javax.persistence.*;
@Entity
public class Vehicle {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
Integer vehicleId;
String vehicleName;
}
One to Many (Unidirectional) Cont.
Person person=new Person();
person.setName("Hibernate");
person.setAge(27);
person.setId(1);
Vehicle vehicle=new Vehicle();
vehicle.setVehicleName("Car");
Vehicle vehicle2=new Vehicle();
vehicle2.setVehicleName("Bike");
person.getVehicle().add(vehicle);
person.getVehicle().add(vehicle2);
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
session.save(person);
session.save(vehicle);
session.save(vehicle2);
session.getTransaction().commit();
session.close();
One to Many (Bidirectional)
import javax.persistence.*;
import java.util.Collection;
import java.util.HashSet;
@Entity
@Table(name = "Employee")
public class Person {
@Id @GeneratedValue(strategy =GenerationType.SEQUENCE )
Integer id;
String name;
Integer age;
@OneToMany
@JoinTable(joinColumns = @JoinColumn(name="USER_ID")
,inverseJoinColumns = @JoinColumn(name = "VEHICAL_ID"))
Collection<Vehicle> vehicle= new HashSet<Vehicle>();
}
import javax.persistence.*;
@Entity
public class Vehicle {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
Integer vehicleId;
String vehicleName;
@ManyToOne
Person person;
}
Person person=new Person();
person.setName("Hibernate");
person.setAge(27);
person.setId(1);
Vehicle vehicle=new Vehicle();
vehicle.setVehicleName("Car");
vehicle.setPerson(person);
Vehicle vehicle2=new Vehicle();
vehicle2.setPerson(person);
vehicle2.setVehicleName("Bike");
person.getVehicle().add(vehicle);
person.getVehicle().add(vehicle2);
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
session.save(person);
session.save(vehicle);
session.save(vehicle2);
session.getTransaction().commit();
session.close();
One to Many (Bidirectional) Cont.
One to Many without additional table
import javax.persistence.*;
import java.util.Collection;
import java.util.HashSet;
@Entity
@Table(name = "Employee")
public class Person {
@Id @GeneratedValue(strategy =GenerationType.SEQUENCE )
Integer id;
String name;
Integer age;
@OneToMany(mappedBy = "person")
Collection<Vehicle> vehicle= new HashSet<Vehicle>();
}
import javax.persistence.*;
@Entity
public class Vehicle {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
Integer vehicleId;
String vehicleName;
@ManyToOne
Person person;
}
Many to Many
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "Employee")
public class Person {
@Id @GeneratedValue(strategy =GenerationType.SEQUENCE )
Integer id;
String name;
Integer age;
@ManyToMany
List<Vehicle> vehicle= new ArrayList<Vehicle>();
}
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Vehicle {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
Integer vehicleId;
String vehicleName;
@ManyToMany(mappedBy = "vehicle")
List<Person> personList = new ArrayList<Person>();
}
Cascade Type
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Person{
@Id @GeneratedValue(strategy = GenerationType.TABLE)
Integer id;
String name;
Integer age;
@OneToMany(cascade = CascadeType.PERSIST)
List<Vehicle> listOfVehicles=new ArrayList<Vehicle>();
}
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Vehicle {
@Id @GeneratedValue(strategy = GenerationType.TABLE)
Integer vehicleId;
String vehicleName;
}
Cascade Type (Cont.)
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Application {
public static void main(String[] args) {
Person person=new Person();
person.setName("Hibernate");
person.setAge(23);
Vehicle vehicle=new Vehicle();
vehicle.setVehicleName("Car");
person.getListOfVehicles().add(vehicle);
SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory();
Session session=sessionFactory.openSession();
session.beginTransaction();
session.persist(person);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
Inheritance
Hibernate provides several strategies to leverage this object-oriented trait onto domain model entities.
MappedSuperclass
When using MappedSuperclass, the inheritance is visible in the domain model only and each database table contains both the base class and the subclass properties.
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
@MappedSuperclass
public class Account {
@Id
private Integer id;
private String owner;
private Integer balance;
private Integer interestRate;
//getters and setters
}
import javax.persistence.Entity;
@Entity
public class DebitAccount extends Account{
private Integer overdraftFee;
//getter and setter
}
DebitAccount debitAccount=new DebitAccount();
debitAccount.setOwner("Peter");
debitAccount.setBalance(23000);
debitAccount.setInterestRate(23);
debitAccount.setId(2);
debitAccount.setOverdraftFee(2300);
session.save(debitAccount);
Single Table
The single table inheritance strategy maps all subclasses to only one database table. Each subclass declares its own persistent properties.
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Account {
@Id
private Integer id;
private String owner;
private Integer balance;
private Integer interestRate;
}
import javax.persistence.Entity;
@Entity
public class DebitAccount extends Account{
private Integer overdraftFee;
// getter and setter
}
Joined Table
Each subclass can also be mapped to its own table. This is also called table-per-subclass mapping strategy. An inherited state is retrieved by joining with the table of the superclass.
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Account {
@Id
private Integer id;
private String owner;
private Integer balance;
private Integer interestRate;
}
import javax.persistence.Entity;
@Entity
public class DebitAccount extends Account{
private Integer overdraftFee;
// getter and setter
}
Table per class
This is called the table-per-concrete-class strategy. Each table defines all persistent states of the class, including the inherited state.
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Account {
@Id
private Integer id;
private String owner;
private Integer balance;
private Integer interestRate;
}
import javax.persistence.Entity;
@Entity
public class DebitAccount extends Account{
private Integer overdraftFee;
// getter and setter
}