0% found this document useful (0 votes)
22 views37 pages

0.hibernate 6 Final

The document outlines a comprehensive Hibernate 6 workshop covering various topics including CRUD applications, relationship mapping, inheritance strategies, and caching mechanisms. It provides practical examples and code snippets for implementing Hibernate features such as entity annotations, primary key generation strategies, and session management. Additionally, it discusses the benefits of using Hibernate, such as lazy loading and automatic dirty checking.

Uploaded by

Suresh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views37 pages

0.hibernate 6 Final

The document outlines a comprehensive Hibernate 6 workshop covering various topics including CRUD applications, relationship mapping, inheritance strategies, and caching mechanisms. It provides practical examples and code snippets for implementing Hibernate features such as entity annotations, primary key generation strategies, and session management. Additionally, it discusses the benefits of using Hibernate, such as lazy loading and automatic dirty checking.

Uploaded by

Suresh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 37

Hibernate 6 workshop:

-----------------------
TOPICS:
======
1. Hello World
2. CRUD application
3. Primary key genearation strategy
4. More annoations
5. Relation mapping
Many-to-one mapping
one-to-one mapping
Many-to-Many mapping

6.Implementing Inheritance in Hibernate


Single Table Strategy
Table Per Class Strategy
Joined Strategy

7. one class to two tables


8. Value type and Embedded Object
9. Saving Collections
10. Introducing HQL and the Query Object
11. Select and Pagination in HQL
12.Understanding Parameter Binding and SQL Injection
13. Hibernate caching
14. Hibernate optimization
13.Named Queries
14. Introduction to Criteria API
15.Understanding Restrictions
16. Cacheing in Hibernate:
First Level and Second Level Cache
17.Using Query Cache in Hibernate
18.Hibernate Batch Processing
19. Hibernate web programming
20. Solving session in view pattern
20. Hibernate caching
21. Hibernate optimization

dependencies: at the end of cheetsheet

Why hibernate?
-------------
->oo way of thinking
->lazy and eager loading
->cascading
->automatic dirty checking
->transactional write behind
->first level caching

Example 1. Hello World hibernate example


------------------------------------
step 1: create maven project with required dependencies
Step 1: copy hibernate.cfg.xml

step 3:create POJO class


public class Customer {
private int id;
private String name;
private String address;
private String mobile;
private String email;
private Date dob;
}

Step 4:Annotate it for Entity

@Table(name = "customer_table")
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
private String address;
private String mobile;
private String email;
private Date dob;
}

step 5: create SessionFactory

StandardServiceRegistryBuilder regbuilder= new

StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();

SessionFactory factory = new


MetadataSources(regbuilder).buildMetadata().buildSessionFactory();

Step 6: Run the application


Session session=factory.openSession();
Transaction tx=session.getTransaction();
try {
tx.begin();
//create and save customer
tx.commit();
}catch(HibernateException ex) {
ex.printStackTrace();
tx.rollback();
}

Example 2: More Annotations:


--------------------------------
@Entity, @Table, @Column, @Temporal, @Transient, @Lob etc

@Entity(name="customer_entity")
@Table(name="customer_table")
public class Customer {
@Id
@Column(name="customer_Id")
private int customerId;
@Column(name="customer_Name")
private String customerName;
@Column(name="customer_Addess")
private String customerAddess;
@Temporal(TemporalType.DATE)
private Date customerDob;
@Transient
private String customerPassword;

Example 3: Mapping Mapping enum : @Enumerated


----------------------------------------------
enum CustomerType {
SILVER, GOLD, DIAMOND
}

@Enumerated(EnumType.STRING)
private CustomerType customerType;

Example 4. CRUD application


------------------------------

public interface CustomerDao {


public List<Customer> getAllCustomers();
public Customer getCustomerById(int customerId);
public Customer addCustomer(Customer customer);
public Customer updateCustomer(Customer customer);
public Customer removeCustomer(int customerId);
}

Note @DynamicUpdate
-------------------
Note: We can apply annotation @DynamicUpdate annotation on pojo, so that
hibernate only
update field that need to, otherwise hibernate try to update all field except
pk
Hibernate fire update iff the state is dirty (dirty checking)

Example 5:Different between session.get() and session.load()


---------------------------------------------------------------
both functions are use to retrieve an object with different mechanism

session.load()
It will always return a proxy (Hibernate term) without hitting the
database.
proxy object look like a temporary fake object.
If no row found , it will throws an ObjectNotFoundException.

session.get()
It always hit the database and return the real object,
an object that represent the database row, not proxy.

If no row found , it return null.

Example 6 :Different Primary key genearation strategy


-----------------------------------------------------
AUTO (ny default :let hibernate make decision)
Identity (Hibernate use identity column)
Sequence
Table

Example table generation strategy


--------------------------------
@TableGenerator
(name="my_gen",table="customerpktable",pkColumnName="customerkey",
pkColumnValue="customervalue",allocationSize=1)
@GeneratedValue(strategy=GenerationType.TABLE,generator="my_gen")

composite uniqe key


--------------------
@Table( name = "MYTABLE",
uniqueConstraints = { @UniqueConstraint( columnNames = { "NAME",
"VERSION" } ) } )

Example 7: Compound Primary Keys


------------------------------------
=> Consider that business requirment is that we need to
represent customer primary key as a combination of
customerId and customerRegistractionId?

=> Compound PK can be created with multiple approaches


1. with @id annotation
2. with @IdClass annotation
3. with @EmbeddedId annotation

with @Id
-----------
Steps:

1. Create an POJO annotated with @Embeddable( it must implements Serilizable


interface and must have default ctr)

@Embeddable
public class CustomerKey implements Serializable{
private static final long serialVersionUID = -4336329019606358832L;
private int customerId;
private String customerRegistrationId;

2. Use it in target class


@Entity
public class Customer {
@Id
private CustomerKey customerKey;
private String customerName;
private String customerAddess;

with @IdClass
----------------
@Entity
@IdClass(EmployeeId.class)
public class Employee {

@Id
private String branchName;
@Id
private int idEmployee;
}

public class EmployeeId implements Serializable {


private int idEmployee;
private String branchName;
}

Example 8: Entity life cycle: Transient, Persistent and Detached Objects


-------------------------------------------------------------------
Consider
--------
@Entity
public class Customer {
@Id
@GeneratedValue
private int id;
private String name;
private String address;

Transient
------------
=>not related to hibernate only in java space not in db space
=>Transient objects do not have association with the databases and session
objects
Customer c=new Customer();
c.setName("raja");
c.setAddress("Delhi");

Persistent
---------
Hibernate care about it

Integer id=(Integer) session.save(c);


Now u can change state of Customer and hibernate keep track of it!
only one update is fired.
c.setAddress("new delhi");
c.setAddress("east delhi");
c.setAddress("noida");

Detached
-----------
=> in java space and in db space
=> The detached object have corresponding entries in the database

session.close();

How State of Object Changes in Hibernate


------------------------------------------

While creating new Entity


--------------------------

new()
|
Transient --> Persistent --> Detached
session.save() session.close();

When Reading an Entity Object


------------------------------

get()
|
Persistent --> Detached
session.close();

When Delete an Entity Object


-----------------------------
Transient <--- Persistent ---> Detached
s.delete() s.close();

Transient <--- Persistent ---> Detached

|<-------------->|
session

=>When object in the session area then it is in Persistent State.

=>When object before the session area then it is in Transient


State.

=>When object after the session area then it is in Detached State.

Detached to Persistent State


--------------------------------

Integer id=(Integer) session.save(c);


session.close();

// time gap

session = fac.openSession();
session.beginTransaction();
c.setAddress("noida");// here user in detached state
session.update(c);
session.getTransaction().commit();

Example 9:Component Mapping


-----------------------------

One class to two tables


------------------------
=> Lets say Customer and other other table CustomerDetails
=> We have to decide what fields should go in each tables?

@Entity
@Table(name="customer")
@SecondaryTable(name="customerDetails")
public class Customer {

@Id
private int customerId;
private String customerName;

//must be in customerDetails table


@Column(table="customerDetails")
private String customerAddess;

@Column(table="customerDetails")
private int customerCreditScore;

@Column(table="customerDetails")
private int customerRewardPoints;
}

Example 9:Relationship mapping:


-----------------------------
in ER diagarm:
-------------
one to many
one to one
many to one
many to many

one to many
--------------
Consider:-
1 N
reverse owner owner of relationship

Department -----------<>------ Employee

public class Employee {

private int empId;


private String empName;
private Department department;
}

public class Department {

private int deptId;


private String detpName;
private List<Employee>employees=new ArrayList<Employee>();
}

@Entity
public class Employee {

@Id
@GeneratedValue
private int empId;
private String empName;

@ManyToOne
private Department department;

@Entity
public class Department {
@Id
@GeneratedValue
private int deptId;
private String detpName;

@OneToMany(mappedBy="department")
private Collection<Employee>employees=new ArrayList<Employee>();

one-to-one mapping
----------------------

In a one-to-one mapping the owner can be


either the source entity or the target entity.

1 1
Employee<>----------Parking

public class Parking {

private int partingId;


private String parkingLocation;

private Employee employee;


}

public class Employee {


private int empId;
private String empName;

private Parking parking;

Now apply annotations


---------------------

@Entity
public class Parking {
@Id
@GeneratedValue
private int partingId;
private String parkingLocation;

@OneToOne(mappedBy = "parking")
private Employee employee;

@Entity
public class Employee {
@Id
@GeneratedValue
private int empId;
private String empName;

@OneToOne
private Parking parking;
}

List<Parking> list=session.createQuery("from Parking p join fetch p.employee


Employee").list();

Criteria criteria = session.createCriteria(Parking.class);


criteria.setFetchMode("employee",FetchMode.EAGER);

@BatchSize(size=5) on emp
http://www.javamakeuse.com/2015/03/tutorial-hibernate-4-batch-fetching.html

from Emp e join fetch e.parking Parking

Many-to-Many mapping
----------------------

N N
Employee----<>----- Project

Create POJO
------------

public class Employee {

private int empId;


private String empName;

private Collection<Project> projects = new ArrayList<Project>();


}

public class Project {


private int projectId;
private String projectName;

private List<Employee> employees = new ArrayList<Employee>();


}
Apply annotations
-------------------
@Entity
public class Employee {
@Id
@GeneratedValue
private int empId;
private String empName;

@ManyToMany
private Collection<Project> projects = new ArrayList<Project>();
}

@Entity
public class Project {
@Id
@GeneratedValue
private int projectId;
private String projectName;

@ManyToMany(mappedBy="projects")
private Collection<Employee> employees = new ArrayList<Employee>();
}

Collection of Basic Types


-----------------------------

One book have many reviews ( of string data type)

@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String isbn;
private String title;
private String author;
private double price;

@ElementCollection(fetch=FetchType.LAZY)
@CollectionTable(name="book_reviews")
@Column(name="review")
private List<String> reviews=new ArrayList<String>();

Inheritance in Hibernate
----------------------------------
DB do not hv notion of Inhertance

Consider:

Account id, name, balance


|
-----------------------
| |

SavingAccount CurrentAccount
intrestRate overdraft

public class Account{


private int accountId;
private String accountHolderName;
private double balance;

//

public class SavingAccount extends Account{


private double intrestRate;

public class CurrentAccount extends Account{


private double overdraft;
}

Single table (single table per hierarchy)


---------------------------------------------

==> Here only one table is going to be created, all fields mapped to single
table.
==> Not very memory efficient, Faster, support polymorphic quaries
==> cant force not null constrants

@Entity
@Table(name = "Account")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)

@DiscriminatorColumn(name="accountType",discriminatorType=DiscriminatorType.STRING)

public class Account {


@Id
@GeneratedValue
private int accountId;
private String accountHolderName;
private double balance;

@Entity
@Table(name="Account")
@DiscriminatorValue("C")
public class CurrentAccount extends Account {
private double overdraft;

@Entity
@Table(name="Account")
@DiscriminatorValue("S")
public class SavingAccount extends Account {
private double intrestRate;

Table per class(Table per concrete class)


--------------------------------------------

==>Two table is going to create SavingAccount and CurrentAccount


==> Sql Union operation is required to get data, Identity auto gen key is not
supported
==> A U B
==> Not Supported by all vendors
==> Do not follow normalization X

@Entity
@Table(name = "Account")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Account{
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private int accountId;
private String accountHolderName;
private double balance;

@Entity
@Table(name="SavingAccount")
public class SavingAccount extends Account{
private double intrestRate;

@Entity
@Table(name="CurrentAccount")
public class CurrentAccount extends Account{
private double overdraft;
}

Joined (as per normalization)


-----------------------------

==>Separate table mapped to all classes in the hierarchy

==> Three table is created Account, SavingAccount, CurrentAccount,


as per normalization, table are need to join to get all data (sql outer
join)

Value type and Embedded Object


------------------------------

Entiy ===>:meaning of its own


value object ====>:dont have meaning of its own
@Embeddable
=> for value object it is not is entity object.
=> Value object means does not have real meaning for self individually.

Addess has to be associated with User otherwise it have no sense.

public class User {


private int userId;
private String userName;

public class Address {


private String city;
private String country;

steps;

1. Apply @Embeddable on value object

@Embeddable
public class Address {
private String city;
private String country;

2.Create ref of Address into User and declare it @Embedded

public class User {


private int userId;
private String userName;

@Embedded
private Addess address;

Saving Collections
-----------------------

What if i need to store more then one address for User?


--------------------------------------
class User{
-----
private int userId;
-----
private Address address1;
private Address address2;
-----
private Address addressN;
-----
}
approach:
----------------------

Set<Address>addresses=new HashSet();
class User{

private int userId;


private String userName;

@ElementCollection
Set<Address>addresses=new HashSet();

@Embeddable
class Address{

private String city;


private String country;

Now save it
-----------------
user.getLisOfAddresses().add(address1);
user.getLisOfAddresses().add(address2);

Save User
two table created : one for user
another with the name : user_addresses hibernate decide for you.

Note:
If u want to hv a custom name

@JoinTable(name="User_address")

Pk of join table is by default is


User_userId (name of the table + pk of User)

How to override it?

@JoinTable(name="User_address", joinColumns=@Joincolumn (name="User_id") )

Set<Address>addresses=new HashSet();
_____________________________

do not support index!

then what?

private Collection<Address> addresses = new ArrayList<Address>();

And use annotation @CollectionId over Collection.


@GenericGenerator(name="hilo-gen", strategy="hilo')
@CollectionId (columns={@Column(name="address_id")}, generator="hilo-gen",
type=@Type(type="long"))

Hibernate batch
----------------

=> how to insert 1000000 records in to database in a time.


=> In Native Solution in the Hibernate

Session session = sessionFactory.openSession();


Transaction tx = session.beginTransaction();
for ( int i=0; i<1000000; i++ )
{
Student student = new Student(.....);
session.save(student);
}
tx.commit();
session.close();

=> by default, Hibernate will cache all the persisted objects in the session-
level cache and ultimately
your application would fall over with an OutOfMemoryException somewhere
around the 50,000th row.

=> You can resolve this problem if you are using batch processing with
Hibernate.

=> To use the batch processing feature, first set hibernate.jdbc.batch_size


as batch size to a number either at 20 or 50 depending on object size.

=> This will tell the hibernate container that every X rows to be inserted as
batch.
To implement this in your code we would need to do little modification as
follows:

Session session = SessionFactory.openSession();


Transaction tx = session.beginTransaction();
for ( int i=0; i<1000000; i++ )
{
Student student = new Student(.....);
session.save(employee);
if( i % 50 == 0 ) // Same as the JDBC batch size
{
//flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
session.close();
code for UPDATE
----------------

Session session = sessionFactory.openSession();


Transaction tx = session.beginTransaction();
ScrollableResults studentCursor = session.createQuery("FROM
STUDENT").scroll();
int count = 0;

while(studentCursor .next())
{
Student student = (Student) studentCursor.get(0);
student.setName("DEV");
seession.update(student);
if ( ++count % 50 == 0 ) {
session.flush();
session.clear();
}
}
tx.commit();
session.close();

<property name="hibernate.jdbc.batch_size"> 50 </property>


<property name="hibernate.cache.use_second_level_cache">false</property>
<property
name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

HQL and the Query Object


---------------------------

==> HQL is OO version of SQL

==> HQL uses class name instead of table name,


and property names instead of column name

==> HQL fully supports polymorphic queries

hibernate queries
_________________

# Hibernate Query Language (HQL)

# Criteria API (JPA 2.x)

# Native SQL queries

HQL Syntax
___________

HQL Queries elements:


____________________
Clauses, Aggregate functions, Subqueries

Clauses in the HQL are:


_______________________
from, select, where, order by, group by

Aggregate functions are:


_______________________

avg(...), sum(...), min(...), max(...) , count(*)


count(...), count(distinct ...), count(all...)

hello World HQL


________________

class Customer{
private int id;
private String name;
private String address;

String q = "FROM Customer c";

Query query = session.createQuery(q);

query.setFirstResult(1);//set first result start value


query.setMaxResults(5);//number of result to be display

List<Customer> cList = query.list();

for(Customer temp : cList)


{
System.out.println(temp);
}

Parameter Binding
__________________

Ex:

String q = "from Customer c where c.address= ?";

Query query = session.createQuery(q);

query.setString(0, "noida");

List result = query.list();

Ex:
Customer c= new Customer ();

c.setName("rajesh");

String hql = "from Customer c where c.name= :name";

Query query = session.createQuery(hql);

query .setString("name","raja");

List result = query.list();

__________________________________
Named Quaries and native Quaries
__________________________________

==> Give unique name to the Queries that work for entire application.

==>The application can use the query by using the name of the query
Ex:

@NamedQueries({@NamedQuery( name = "findCustomer.byId",query = "from Customer


c where c.id = :id" )})

@NamedNativeQueries({
@NamedNativeQuery(
name = "findCustomer.byAddress", query = "select * from Customer c
where c.address = :address" , resultClass = Customer.class
)
})

@Entity
public class Customer {
@Id
@GeneratedValue
private int id;

now Use Query:


--------------------

Query query =
session.getNamedQuery("findCustomer.byId").setInteger("id", 3);

List<Customer> cList = query.list();


for(Customer temp : cList)
{
System.out.println(temp);
}
Using HQL CRUD methods:
_______________________

Delete:
_______
String HQL = "DELETE FROM Customer WHERE id=:id";
Query query = session.createQuery(HQL);
query.setParameter("id", 5);
session.beginTransaction();
int executeUpdate = query.executeUpdate();
session.getTransaction().commit();
if(executeUpdate>0)
System.out.println("custoemr is deleted..");

Update:
_______

String HQL = "UPDATE Customer set address=:address WHERE id=:id";

Query query = session.createQuery(HQL);


query.setParameter("address", "delhi");
query.setParameter("id", 5);

session.beginTransaction();
int executeUpdate = query.executeUpdate();
session.getTransaction().commit();
if(executeUpdate>0)
System.out.println("customer email is updated..")

Insert:
________
String HQL = "INSERT INTO
Employee(employeeName,doj,salary,bonus,email,designation)"+
"SELECT employeeName,doj,salary,bonus,email,designation FROM
BackupEmployee";

Query query = session.createQuery(HQL);


session.beginTransaction();
int executeUpdate = query.executeUpdate();
if(executeUpdate>0)
System.out.println(executeUpdate+" records are inserted
successfully..");

_________________________
Criteria API in Hibernate
___________________________

3 way to pulling data from the database in the Hibernate.


____________________________________________________________

1. Using session methods(get() and load() methods)


-limited control to accessing data
2. Using HQL - Slightly more control using where clause

3. Using Criteria API


The criteria API is an alternative of HQL queries.
It is more powerful and flexible for writing tricky
criteria functions and dynamic queries

Criteria hello world


____________________

Criteria criteria = session.createCriteria(Customer.class);

criteria.add(Restrictions.eq("name", "amit"));

criteria.add(Restrictions.le("id", 5));

List<Customer> cList = criteria.list();

Note:
------

Restrictions.ge

Restrictions.le

Restrictions.ne

Restrictions.in
------------------------
Criteria criteria = session.createCriteria(Customer.class);

criteria.add(Restrictions.in("id", new Integer[]{3,5,7}));

List list = criteria.list();

Restrictions.like
------------------

Criteria criteria = session.createCriteria(Customer.class);


criteria.add(Restrictions.like("name", "%raja%"));
List list = criteria.list();

Restrictions.isNull
_________________

Criteria criteria = session.createCriteria(Customer.class);

criteria.add(Restrictions.isNull("address"));

List list = criteria.list();

Restrictions.isNotNull
Restriction.between
_________________

Criteria criteria = session.createCriteria(Customer.class);

criteria.add(Restrictions.between("id", 3, 7));

List list = criteria.list();

Restriction.allEq
_________________

SELECT * FROM user WHERE userName = +userName AND userPassword =


+userPassword;

Map map = new HashMap();


map.put("username", username);
map.put("userPassword", userPassword);
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.allEq(map));
List list = criteria.uniqueResult();

________________
JPQL examples:
______________

@Table(name = "person_table")
@Entity(name="people")
public class Person {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
private String email;

@Temporal(TemporalType.DATE)
private Date birthDate;
}

Main:
______
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("demo");
EntityManager em = factory.createEntityManager();
EntityTransaction transaction = em.getTransaction();

transaction.begin();
Person p = new Person("raj", "gupta", "[email protected]", new Date());
em.persist(p);
em.createQuery("from people");
em.createNativeQuery("select * from person_table");
transaction.commit();
em.close();

______
joins
_______

@Entity
@NamedQueries({
@NamedQuery(name="Person.everyone", query = "from Person")
})
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;

@ManyToOne(cascade = CascadeType.PERSIST)
private Address address;

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "person_id")
private List<PhoneNumber> numbers = new ArrayList<>();

public Person(String firstName, String lastName) {


this.firstName = firstName;
this.lastName = lastName;
}

public void addPhonenumber(PhoneNumber phoneNumber) {


numbers.add(phoneNumber);
}

@Entity
public class PhoneNumber {
@Id
@GeneratedValue
private Long id;
private String number;
private String type;

public PhoneNumber(String number, String type) {


this.number = number;
this.type = type;
}
}

@Entity
public class Address {
@Id
@GeneratedValue
private Long id;
private String street;
private String city;
private String state;
private String zip;

public Address(String street, String city, String state, String zip) {


this.street = street;
this.city = city;
this.state = state;
this.zip = zip;
}
}

Quaries examples:
_________________

gettting all persons:


_________________

TypedQuery<Person> query = em.createQuery("from Person", Person.class);


List<Person> personList = query.getResultList();

Using named quaries:


_________________
TypedQuery<Person> query = em.createNamedQuery("Person.everyone",
Person.class);
List<Person> personList = query.getResultList();

polymorphicQuery
_________________

TypedQuery<Account> query = em.createQuery("from Account", Account.class);


List<Account> accounts = query.getResultList();

aliasesQuery
____________

TypedQuery<Person> query = em.createQuery("from Person as p where p.id = 1",


Person.class);

pagination
______________

TypedQuery<Person> query = em.createQuery("from Person", Person.class);


query.setFirstResult(7);
query.setMaxResults(5);
List<Person> people = query.getResultList();
System.out.println(people.size());

orderBy
_________

TypedQuery<Person> query = em.createQuery("from Person p order by p.lastName


desc", Person.class);
List<Person> personList = query.getResultList();

whereClause
___________

TypedQuery<Person> query = em.createQuery("from Person p where p.lastName


like '%n%'", Person.class);
List<Person> personList = query.getResultList();

queryParameters
_____________

//NOT Good
TypedQuery<Person> query =
em.createQuery("from Person p where p.firstName =
'"+firstName+"'", Person.class);

1. Named Parameters
_________________

TypedQuery<Person> query = em.createQuery("from Person p where


p.firstName = :first", Person.class);
query.setParameter("first", firstName);

2. position
_______________

TypedQuery<Person> query =
em.createQuery("from Person p where p.lastName = ?1 and p.firstName =
?0", Person.class);
query.setParameter(0, "raj");
query.setParameter(1, "gupta");

List<Person> personList = query.getResultList();

singleResult
_________________

TypedQuery<Person> query = em.createQuery("from Person p where p.id = 123",


Person.class);
// Person p = query.getSingleResult();
// System.out.println(p);
query.setMaxResults(1);
List<Person> p = query.getResultList();
System.out.println(p.size());
// System.out.println(p.get(0));

specialAttributeId
_________________

Consider:
-------
public class Person {
@Id
@GeneratedValue
private Long personId;
}

TypedQuery<Person> query = em.createQuery("from Person p where p.id = 1",


Person.class);

List<Person> p = query.getResultList();

__________
join
___________

1. implicit join
_________________

TypedQuery<Person> query = em.createQuery("from Person p where


p.address.state = 'delhi'", Person.class);

2. explicit join
TypedQuery<Person> query =
em.createQuery("select p from Person p join p.address addr where
addr.state = 'delhi'", Person.class);

List<Person> p = query.getResultList();

Join 1 to many:
_________________

1 1
Person--------<>--------Phone

TypedQuery<Object[]> query =
em.createQuery("from Person p join p.numbers n where n.number like
'641%'", Object[].class);
List<Object[]> list = query.getResultList();
for(Object[] obj : list){
System.out.println((Person)obj[0]);
System.out.println((PhoneNumber)obj[1]);
}

use select clause


_________________

TypedQuery<Person> query2 =
em.createQuery("select p from Person p join p.numbers n where n.number like
'641%'", Person.class);
List<Person> personList = query2.getResultList();
use DISTINCT keyword
_________________

TypedQuery<Person> query2 =
em.createQuery("select distinct p from Person p join p.numbers n where
n.number like '641%'", Person.class);
List<Person> personList = query2.getResultList();
System.out.println(personList);

joinFetch
__________

TypedQuery<Person> query2 =
em.createQuery("from Person p join fetch p.numbers n where n.number
like '641%'", Person.class);
List<Person> personList = query2.getResultList();

hibernate performace:
_______________________

hibernate Optimization:
_______________________
N+1 problem

Dynamic solution:
__________________

Entity graph (jpa 2.1) left outer join


join fetch : inner join

static solution:
_________________

@BatchSize : convert N+1 problem to N/batchsize +1 problem


@Fetch(subselect) N+1 to 1+1 subselect

@LazyCollection(LazyCollection.EXTRA)

class Dept{
@OneToMany
@JoinColumn
@LazyCollection(LazyCollection.EXTRA)
List<Emp> emp=new AL<>();

dept
dept.getEmps().size()

consider example:
__________________

1 1
customer ------------------ Address
|
| N
------------------------- Book
|
| N
------------------------ Movie
|
| 1
N ------------------------- SalesRep

@Entity
public class Customer {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;

@OneToOne(cascade = CascadeType.ALL)
private Address address;

@OneToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)


@OneToMany(cascade = CascadeType.PERSIST)
@JoinColumn
@LazyCollection(LazyCollectionOption.EXTRA)
private List<Book> books = new ArrayList<>();

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn
private List<Movie> movies = new ArrayList<>();

@ManyToOne(cascade = CascadeType.ALL)
private SalesRep salesRep;
}

@Entity
public class Address {
@Id
@GeneratedValue
private Long id;
private String city;
private String state;
}

@Entity
public class Author {
@Id
@GeneratedValue
private Long id;
private String name;

public Author(String name) {


this.name = name;
}
}

@Entity
public class Book {
@Id
@GeneratedValue
private Long id;
private String name;

@OneToOne(cascade = CascadeType.ALL)
private Author author;
}

@Entity
public class Movie {
@Id
@GeneratedValue
private Long id;
private String name;

public Movie(String name) {

this.name = name;
}

@Entity
public class SalesRep {
@Id
@GeneratedValue
private Long id;
private String name;

@OneToMany(mappedBy = "salesRep", cascade = CascadeType.ALL, fetch =


FetchType.LAZY)
// @BatchSize(size = 3)
@Fetch(FetchMode.SUBSELECT)
private List<Customer> customers = new ArrayList<>();

@OneToOne(cascade = CascadeType.ALL)
private Address address;
}

lazy or Eager
___________

TypedQuery<Customer> query = em.createQuery("from Customer", Customer.class);

List<Customer> customers = query.getResultList();

for (Customer c : customers) {


System.out.println(c.getAddress());
System.out.println(c.getBooks().size());// we just want to print no of books
//@LazyCollection(LazyCollectionOption.EXTRA)
}

class A{

private List<B> bs=....


private List<c> bs=....

cartesianProduct_BAD
______________________

TypedQuery<Object[]> query = em.createQuery("from Customer c left join


c.books left join c.movies", Object[].class);
query.getResultList();

nPlusOneProblem
________________

TypedQuery<SalesRep> query = em.createQuery("from SalesRep", SalesRep.class);


List<SalesRep> list = query.getResultList();

entityGraphAndJoinFetch
________________________

1. Use entity graph


_______________

TypedQuery<Customer> query = em.createQuery("from Customer",


Customer.class);
EntityGraph<Customer> entityGraph = em.createEntityGraph(Customer.class);
entityGraph.addAttributeNodes("address");
entityGraph.addSubgraph("books").addAttributeNodes("author");
query.setHint("javax.persistence.fetchgraph", entityGraph);

2. Join Fecth
_________________

TypedQuery<Customer> query =
em.createQuery("from Customer c join fetch c.address join fetch c.books b
join fetch b.author", Customer.class);

___________________________
Hibernate caching example:
____________________________

http://howtodoinjava.com/2013/07/04/hibernate-ehcache-configuration-tutorial/

Step 1: enable caching in hibernate configuration file


<?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 setting -->
<property name="connection.url">jdbc:mysql://localhost:3306/yms_demo2?
useSSL=false</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property
name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<property name="show_sql">true</property>

<property name="format_sql">true</property>
<!-- disable the second level cache * -->
<property
name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegi
onFactory</property>
<property
name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_query_cache">true</property>

<property name="hibernate.cache.use_second_level_cache">true</property>
<property
name="hibernate.cache.region.provider_class">net.sf.ehcache.hibernate.EhCacheProvid
er</property>
<property name="hbm2ddl.auto">update</property>
<!-- jdbc connection pool build in -->
<property name="connection.pool_size">1</property>
<!-- <property name="current_session_context_class">thread</property>
-->

<mapping class="com.demo.Customer" />

</session-factory>
</hibernate-configuration>

step 2:Apply caching technique at pojo level

@Entity
@Table(name="customer_table2")
@Cacheable
//@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

private String name;


private String address;

SessionFactory factory=null;
try{
factory=new AnnotationConfiguration()
.configure("hibernate2.cfg.xml").buildSessionFactory();

Session session=factory.openSession();
session.getTransaction().begin();

Customer customer=(Customer) session.get(Customer.class, 1);

session.getTransaction().commit();
session.close();

Session session2=factory.openSession();
session2.getTransaction().begin();

Customer customer2=(Customer) session2.get(Customer.class, 1);

session2.getTransaction().commit();
session2.close();

}finally{
if(factory!=null)
factory.close();
}

Query cahche example:


_____________________

//Query cache
Query query=session.createQuery("from Customer where id=121");
query.setCacheable(true);

Customer customer2=(Customer) query.uniqueResult();

Enable query chache in configuration file


------------------------------------
<property name="hibernate.cache.use_query_cache">true</property>

Case studies examples:


______________________
try step by step:
_________________

mapping
one to many
one to one: unidirectional bidirectional
try ex to understand N+1
many to many, use @joinTable and @joinColumn annotation
inheritance:
single table per class her
jointed
table per class

1. Zoo management application: refer pdf

2. Book management application


______________________________

Domain design
______________

N M 1 N
- Book --------<>------- Author ----<>-------Address
|
----- List of phones
|
------List of emails
1 N
- Book --------<>------- Review

- Book
|
-----
| |
Ebook PaperBook

- Book ------<>--------- Publisher --<>-------OfficeAddress

___________________________________________________________________________________
____________________________________

one to one : uni:


___________________

Employee employee1=new Employee("raj");


Employee employee2=new Employee("ekta");
Employee employee3=new Employee("gun");
Employee employee4=new Employee("keshav");
Employee employee5=new Employee("vikas");

Parking parking1=new Parking("A12");


Parking parking2=new Parking("M2");
Parking parking3=new Parking("B2");
Parking parking4=new Parking("T11");
Parking parking5=new Parking("U12");

parking1.setEmployee(employee1);
parking2.setEmployee(employee2);
parking3.setEmployee(employee3);
parking4.setEmployee(employee4);
parking5.setEmployee(employee5);

Session session=factory.openSession();

session.getTransaction().begin();

session.persist(parking1);
session.persist(parking2);
session.persist(parking3);
session.persist(parking4);
session.persist(parking5);

//
// session.persist(employee1);
// session.persist(employee2);
// session.persist(employee3);
// session.persist(employee4);
// session.persist(employee5);
//

one to one bi directinal:


_________________________

Employee employee1 = new Employee("sumit");


Employee employee2 = new Employee("ekta");
Employee employee3 = new Employee("gun");
Employee employee4 = new Employee("keshav");
Employee employee5 = new Employee("vikas");

Parking parking1 = new Parking("A12");


Parking parking2 = new Parking("M2");
Parking parking3 = new Parking("B2");
Parking parking4 = new Parking("T11");
Parking parking5 = new Parking("U12");

parking1.setEmployee(employee1);
parking2.setEmployee(employee2);
parking3.setEmployee(employee3);
parking4.setEmployee(employee4);
parking5.setEmployee(employee5);

employee1.setParking(parking1);
employee2.setParking(parking2);
employee3.setParking(parking3);
employee4.setParking(parking4);
employee5.setParking(parking5);

session.persist(parking1);
session.persist(parking2);
session.persist(parking3);
session.persist(parking4);
session.persist(parking5);

one to many data:


____________________

Department department1=new Department("IT");


Department department2=new Department("sales");
Department department3=new Department("mkt");
Department department4=new Department("r&d");

Employee employee1=new Employee("raja");


Employee employee2=new Employee("amit");
Employee employee3=new Employee("sumit");
Employee employee4=new Employee("ekta");

Employee employee5=new Employee("keshav");


Employee employee6=new Employee("gunika");
Employee employee7=new Employee("rajiv");

department1.getEmployees().add(employee1);
department1.getEmployees().add(employee2);

department2.getEmployees().add(employee3);
department2.getEmployees().add(employee4);

department3.getEmployees().add(employee5);
department3.getEmployees().add(employee6);
department3.getEmployees().add(employee7);

employee1.setDepartment(department1);
employee2.setDepartment(department1);

employee3.setDepartment(department2);
employee4.setDepartment(department2);

employee5.setDepartment(department3);
employee6.setDepartment(department3);
employee7.setDepartment(department3);

session.save(department1);
session.save(department2);
session.save(department3);

session.save(employee1);
session.save(employee2);
session.save(employee3);
session.save(employee4);
session.save(employee5);
session.save(employee6);
session.save(employee7);
References:
----------
http://learningviacode.blogspot.in/2012/02/hibernate-object-life-cycle.html
https://www.objectdb.com/

@Formula
__________

annotation to provide a SQL snippet. Hibernate


executes it when it fetches the entity from the database. The return value of the
SQL expression gets mapped to a read-only entity attribute

@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false)
private Long id;
@Column
private LocalDate dateOfBirth;
@Formula(value = "date_part('year', age(dateOfBirth))")
private int age;

@PrePersist
___________

The JPA specification defines a set of callback annotations to trigger method


calls for certain lifecycle events. If you want to initialize an entity attribute

before it gets persisted, you just have to do 2 things:


1. Add a method to the entity that initializes the attribute.
2. Annotate this method with @PrePersist so that Hibernate calls it before
it persists the entity.

@Entity
public class Author {
...
@PrePersist
private void initializeCreatedAt() {
this.createdAt = LocalDateTime.now();
log.info("Set createdAt to "+this.createdAt);
}
}

hib lob:
------
https://www.baeldung.com/hibernate-lob
hib life cycle:
------------
http://learningviacode.blogspot.com/2012/02/hibernate-object-life-cycle.html

Hibernate conf with connection pooling


_________________________________-

configure connection pooling with tomcat!

Step 1: mapping in context.xml


____________________

<Resource
name="jdbc/test"
auth="Container"
driverClassName="com.mysql.jdbc.Driver"
type="javax.sql.DataSource"
url="jdbc:mysql://localhost:3306/exp121"
username="root"
password="root" >
</Resource>

Step 2:mapping in web.xml


____________________
<resource-ref>
<description>Test Database</description>
<res-ref-name>jdbc/test</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>

Step 3:apply annotation DI


__________________________

@Resource(name="jdbc/test")
private DataSource ds;
private Connection conn;

conn = ds.getConnection();

then use connection object as usual;

configure connetion pool hibernate:


___________________________________
<session-factory>
<property
name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property
name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property
name="hibernate.connection.datasource">java:comp/env/jdbc/test</property>
<property
name="hibernate.current_session_context_class">thread</property>
</session-factory>

dependencies:
--------------

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<hibernate.version>6.1.5.Final</hibernate.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mysql.version>8.0.31</mysql.version>
</properties>

<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.0</version>
</dependency>
<!-- JAXB Implementation -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>3.0.0</version>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>

</dependencies>

You might also like