SlideShare a Scribd company logo
Accessing Data Through
Hibernate; What DBAs Should
Tell Developers and Vice Versa
Marco Tusa and Francisco Bordenave
Percona
2
Who Are We?
Marco
Francisco
3
Agenda
1. Basic description of Hibernate architecture
2. Basic description of MySQl architecture
3. What is an Object entity in Hibernate?
4. What it means for a DB?
5. JDBC
6. Simple example with One table (employees) as object
7. What it is employees as DB object?
8. CRUD example with SQL generation
9. What is the overhead in using Hibernate?
10.What is a composite object and what is the impact?
11.Can we do better?
4
Introduction / Disclaimer
the important … is to have clear ideas and coordinated direction What is this fish?
I didn’t ask for sushi
Java?
Why is he talking
about coffee, I
ordered sushi!
5
Hibernate Basic Architecture
Benefit from developer’s point of view:
● Object-relational mapping (ORM)
● Makes it easy to access data
● Rows become objects
● Don’t have to deal with how data is accessed
● Data persist in the application after query
● I can access multiple sources with
same logic/code
In short my life is easier without dealing with SQL
6
DBA
Let’s see a very high level and basic description of internals
7
DBA
8
DBA
EASY RIGHT?
9
DBA
Now being serious
MySQL is the RDBMS
InnoDB is the engine
Data is organized in 16kb pages
Clustered Primary Key and then secondary indexes
1
0
DBA
Now being serious
MySQL is the RDBMS
InnoDB is the engine
Data is organized in 16kb pages
Clustered Primary Key and then secondary indexes
InnoDB supports transactions (i.e. BEGIN/COMMIT) and has ACID capabilities:
● Atomicity
● Consistency
● Isolation
● Durability
Isolation means transactions should not affect other transactions when running concurrently.
1
1
Data Access Using Hibernate
● So I have a DB
● My code
● JDBC
● Hibernate
If I have Hibernate why I need to know all
these additional things?
I just need:
● Hibernate SessionFactory (heavy to create
and one for Application or by data store)
● Hibernate Session, light, ephemeral,
Open-close it inside nuclear operations
1
2
What is an Entity? And States?
I need to know that I have this:
1
3
Simple example with One table employees
● Mapping definition
● Code
What is an Entity?
<hibernate-mapping package="net.tc.employees">
<class
name="Employees"
table="employees"
catalog="employees"
optimistic-lock="version">
<id
name="empNo"
type="int">
<column name="emp_no" />
<generator class="assigned" />
</id>
<property
name="birthDate"
type="date"
>
<column name="birth_date"
length="10" not-null="true" />
<property
name="firstName"
type="string"
>
<column name="first_name"
length="14" not-null="true" />
public class Employees implements java.io.Serializable {
private int empNo;
private Date birthDate;
private String firstName;
private String lastName;
private char gender;
private Date hireDate;
private Set titleses = new HashSet(0);
private Set salarieses = new HashSet(0);
private Set deptEmps = new HashSet(0);
private Set deptManagers = new HashSet(0);
public Employees() {
}
public Employees(int empNo, Date birthDate, String
firstName, String lastName, char gender, Date hireDate) {
this.empNo = empNo;
this.birthDate = birthDate;
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.hireDate = hireDate;
}
DBA
So what’s an entity in relational database?
DBA
So what is an entity in a relational database?
Simple: it is a row in the table
show create table employeesG
*************************** 1. row ***************************
Table: employees
Create Table: CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` enum('M','F') NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.01 sec)
show create table salariesG
*************************** 1. row ***************************
Table: salaries
Create Table: CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`),
KEY `emp_no` (`emp_no`),
CONSTRAINT `salaries_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
1
6
Connection Pool + JDBC Pollution
Connections:
Important to know that a connection=thread in MySQL.
Thread allocates buffers (tmp_table_size, sort_buffer_size, etc) --> Thread = CPU
and Memory work.
The more the threads, the more the CPU and Memory pressure.
1
7
Connection Pool + JDBC Pollution
Connections:
Inside MySQL 2 ways of handling threads (thread_handling variable):
- 1 thread per each connection - one-thread-per-connection (thread_cache_size)
- pool of threads - loaded_dinamically (thread_pool_size) - Enterprise feature
- Percona Server has a thread pool library pool-of-threads
Rule of thumb:
- In MySQL most of use cases are handled properly with
one_thread_per_connection
- Thread pool fits only in few use cases: normally high number of threads running
very short queries.
1
8
Connection Pool + JDBC Pollution
Connections
Out of MySQL
JDBC
- API for connecting to MySQL from Java App
- Several connection pool handlers
- Hikari -> standard nowadays
- c3p0 (still common but no longer recommended)
1
9
Connection Pool + JDBC Pollution
Connection Pool:
Connection pool as external concept VS internal Connection pool
In MySQL: group of connections (threads) constantly opened and re used.
Out of MySQL: group of connections handled by framework which may or not be kept opened.
JDBC pollution (a.k.a. damn defaults):
Simple connection without optimization
/* mysql-connector-java-8.0.12 (Revision: 24766725dc6e017025532146d94c6e6c488fb8f1) */SELECT
@@session.auto_increment_increment AS auto_increment_increment, @@character_set_client AS
character_set_client, @@character_set_connection AS character_set_connection,
@@character_set_results AS character_set_results, @@character_set_server AS character_set_server,
@@collation_server AS collation_server, @@init_connect AS init_connect, @@interactive_timeout AS
interactive_timeout, @@license AS license, @@lower_case_table_names AS lower_case_table_names,
@@max_allowed_packet AS max_allowed_packet, @@net_write_timeout AS net_write_timeout,
@@query_cache_size AS query_cache_size, @@query_cache_type AS query_cache_type, @@sql_mode AS
sql_mode, @@system_time_zone AS system_time_zone, @@time_zone AS time_zone, @@transaction_isolation
AS transaction_isolation, @@wait_timeout AS wait_timeout;
2
0
Connection Pool + JDBC Pollution
Noise exists, but can be reduced:
hibernate.hikari.dataSource.cachePrepStmts">true
hibernate.hikari.dataSource.defaultFetchSize">100
hibernate.hikari.dataSource.prepStmtCacheSize">250
hibernate.hikari.dataSource.prepStmtCacheSqlLimit">2048
hibernate.hikari.dataSource.useServerPrepStmts">true
hibernate.hikari.dataSource.useLocalSessionState">true
hibernate.hikari.dataSource.rewriteBatchedStatements">true
hibernate.hikari.dataSource.cacheResultSetMetadata">true
hibernate.hikari.dataSource.cacheServerConfiguration">true
hibernate.hikari.dataSource.elideSetAutoCommits">true
hibernate.hikari.dataSource.maintainTimeStats">false
For Hibernate you must add in URL
jdbc:mysql://127.0.0.1:3306/employees?prepStmtCacheSize=250&am
p;prepStmtCacheSqlLimit=2048&amp;useServerPrepStmts=YES&amp;us
eLocalSessionState=YES&amp;useSSL=false&amp;defaultFetchSize=1
00&amp;rewriteBatchedStatements=YES&amp;cacheResultSetMetadata
=YES&amp;cacheServerConfiguration=YES&amp;elideSetAutoCommits=
YES&amp;maintainTimeStats=false
Now For Some More Insight
2
2
Developer CRUD Code Hibernate
Insert
Session se = sessionFactoryEmp2.openSession();
se.setJdbcBatchSize(1);
se.beginTransaction();
int i=1;
while(++i < 500) {
Employees employee = new Employees();
employee.setBirthDate(new Date());
employee.setHireDate(new Date());
employee.setGender('M');
employee.setEmpNo(i);
employee.setFirstName("Franco" + 1);
employee.setLastName("Castagna"+i);
se.save(employee);
}
se.getTransaction().commit();
se.close();
Read
Session se = sessionFactoryEmp2.openSession();
se.setJdbcBatchSize(1);
se.beginTransaction();
List<Employees> employees = se.createQuery("from Employees where emp_no <999 "
).list();
se.disconnect();
se.close();
Update
se.beginTransaction();
List<Employees> employees = se.createQuery("from Employees where emp_no <999 "
).list();
int i = 0;
Iterator it = employees.iterator();
while(it.hasNext()) {
Employees myEmp = (Employees) it.next();
try{myEmp.setHireDate(this.getSimpleDateFormat().parse("2015-"+
getRandomNumberInRange(1,12) +"-10"));}catch(Exception ae ) {ae.printStackTrace();}
se.update(myEmp);
}
se.getTransaction().commit();
se.disconnect();
se.close();
2
3
Developer CRUD Code Simple Code No Batch
Insert
Statement stmt = conn.createStatement();
int i=0;
StringBuffer sb =new StringBuffer();
String sqlHead="INSERT INTO employees
(emp_no,birth_date,first_name,last_name,gender,hire_date)
VALUES (";
stmt.execute("START TRANSACTION");
while(++i < 500) {
sb.append(i);
sb.append(",’”+
this.getSimpleDateFormat().format(new Date())
+"'");
sb.append(",'Franco"+ i +"'");
sb.append(",'Castagna"+ i +"'");
sb.append(",'M'");
sb.append(",’”+
this.getSimpleDateFormat().format(new Date())
+"'");
sb.append(")");
stmt.execute(sqlHead+sb.toString());
sb.delete(0,sb.length());
}
conn.commit();
Read
StringBuffer sb =new StringBuffer();
String sqlHead="SELECT emp_no,birth_date,first_name,last_name,gender,hire_date
FROM employees where emp_no=";
int rowReturned=0;
while(++i < 500) {
sb.append(i);
ResultSet rs = stmt.executeQuery(sqlHead+sb.toString());
HashSet employees = new HashSet();
while(rs.next()) {
Employees employee = new Employees();
employee.setBirthDate(rs.getDate("birth_date"));
employee.setHireDate(rs.getDate("hire_date"));
employee.setGender( rs.getString("gender").charAt(0));
employee.setEmpNo(rs.getInt("emp_no"));
employee.setFirstName(rs.getString("first_name"));
employee.setLastName(rs.getString("last_name"));
employees.add(employee);
}
}
Delete
Statement stmt = conn.createStatement();
int i=0;
String sqlHead="Delete from employees where emp_no=";
stmt.execute("START TRANSACTION");
while(++i < 500) {
stmt.execute(sqlHead+i);
}
conn.commit();
DBA
Where is the overhead in:
- Additional not useful SQL
- too many temporary tables on disk
- causes IO overhead
- Duplicated SQL
- too many show/set commands
- causes CPU/Memory overhead
- Not optimized SQL (like batching and so on)
- Queries coming from framework are generally not properly optimized
- Poorly optimized queries hit everything: CPU/Memory/IO
Evidence
Hibernate
# Time: 2019-05-14T11:27:20.481014Z
# User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1919
# Query_time: 0.000008 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
SET timestamp=1557833240;
# administrator command: Close stmt;
# Time: 2019-05-14T11:27:20.481484Z
# User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1919
# Query_time: 0.000059 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
SET timestamp=1557833240;
# administrator command: Prepare;
# Time: 2019-05-14T11:27:20.482054Z
# User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1919
# Query_time: 0.000091 Lock_time: 0.000029 Rows_sent: 0 Rows_examined: 0
SET timestamp=1557833240;
insert into employees.employees (birth_date, first_name, last_name, gender, hire_date,
emp_no) values ('2019-05-14', 'Franco1', 'Castagna2', 'M', '2019-05-14', 2);
Evidence
Standard call/code
SET timestamp=1557833376;
INSERT INTO employees (emp_no,birth_date,first_name,last_name,gender,hire_date) VALUES
(1,'2019-05-14','Franco1','Castagna1','M','2019-05-14');
# Time: 2019-05-14T11:29:36.974274Z
# User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1934
# Query_time: 0.000082 Lock_time: 0.000033 Rows_sent: 0 Rows_examined: 0
SET timestamp=1557833376;
INSERT INTO employees (emp_no,birth_date,first_name,last_name,gender,hire_date) VALUES
(2,'2019-05-14','Franco2','Castagna2','M','2019-05-14');
2
7
Developer - CRUD Results No Batch
What Can Be Done? - Batch
Hibernate configuration
<hibernate-configuration>
<session-factory >
<property name="sessionFactoryName">Hikari</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.jdbc.batch_size">20</property>
Java code Hibernate related
Session se = sessionFactoryEmp2.openSession();
se.setJdbcBatchSize(20);
se.beginTransaction();
while(i < 500) {
Employees employee = new Employees();
employee.setBirthDate(new Date());
...
se.save(employee);
if ( ++i % 20 == 0 ) { //20, same as the JDBC batch sizeflush a batch of inserts and release
memory:
se.flush();
se.clear();
}
}
What Can Be Done? - Batch
Hibernate
SET timestamp=1557833655;
insert into employees.employees (birth_date, first_name, last_name, gender, hire_date,
emp_no) values ('2019-05-14', 'Franco1', 'Castagna1', 'M', '2019-05-14', 1),...,('2019-05-14',
'Franco1', 'Castagna19', 'M', '2019-05-14', 19);
# Time: 2019-05-14T11:34:15.998326Z
# User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1945
# Query_time: 0.000024 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
SET timestamp=1557833655;
# administrator command: Close stmt;
# Time: 2019-05-14T11:34:15.998609Z
# User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1945
# Query_time: 0.000008 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
3
0
Developer - CRUD Results With Batch
3
1
CRUD Summary With Optimization
DBA - What is That Traffic?
● A lot of data is read from the DB over and over
● Tons of simple queries
● Queries involves also referenced tables and not only the main one
3
3
Developer - Entity and References
3
4
Developer Entity and References
Let us start with the cool things:
Session se = sessionFactoryEmp2.openSession();
se.beginTransaction();
Employees myEmp = se.find(Employees.class,10001, LockModeType.PESSIMISTIC_WRITE);
Set salaries = null;
salaries = myEmp.getSalarieses();
Iterator itS = salaries.iterator();
while(itS.hasNext()) {
Salaries mySal = (Salaries) itS.next();
if(mySal.getToDate().toString().equals("9999-01-01")){
mySal.setSalary(mySal.getSalary() + 100);
}
}
se.saveOrUpdate(myEmp);
se.getTransaction().commit();
se.disconnect();
se.close();
Performance
ALERT
3
5
Developer Entity and References
Employees myEmp = se.find(Employees.class,10001, LockModeType.PESSIMISTIC_WRITE);
● Hibernate: select employees0_.emp_no as emp_no1_3_0_... from employees.employees employees0_
where employees0_.emp_no=? for update
salaries = myEmp.getSalarieses();
● Hibernate: select salarieses0_.emp_no as emp_no1_4_0_... from employees.salaries salarieses0_ where
salarieses0_.emp_no=?
se.saveOrUpdate(myEmp);
● Hibernate: update employees.salaries set salary=?, to_date=? where emp_no=? and from_date=?
3
6
Developer Entity and References
● Entities and sets (References)
● Great to have them (sets) but sometime they stab you in the back!
● What is Lazy and how to control it ... if you can!
● A few tests will follow:
○ Get (select) Employees Lazy/Not Lazy Hibernate versus simple code
○ Update a Salary value for a given employee
3
7
Entity and references the Lazy factor
Remember this?
Entity and References - the Lazy Factor
<set name="salarieses" table="salaries" lazy="true|false" fetch="select" >
<key>
<column name="emp_no" not-null="true" />
</key>
<one-to-many class="net.tc.employees.Salaries"/>
</set>
LAZY
List<Employees> employees = se.createQuery("from EmployeesSummary where emp_no >10000 and emp_no < 20020 " ).list();
Iterator it = employees.iterator();
while(it.hasNext()) {
Employees myEmp = (Employees) it.next();
logger.info("EmployeeSummary name = " + myEmp.getFirstName()+" "+ myEmp.getLastName());
Iterator it2 = myEmp.getTitleses().iterator(); ← HERE I retrieve the info
Iterator it3 = myEmp.getSalarieses().iterator(); ← HERE I retrieve the info
Iterator it4 = myEmp.getDeptEmps().iterator(); ← HERE I retrieve the info
}
NOT LAZY
List<Employees> employees = se.createQuery("from EmployeesSummary where emp_no >10000 and emp_no < 20020 " ).list(); ← HERE
Iterator it = employees.iterator();
while(it.hasNext()) {
Employees myEmp = (Employees) it.next();
logger.info("EmployeeSummary name = " + myEmp.getFirstName()+" "+ myEmp.getLastName());
Iterator it2 = myEmp.getTitleses().iterator();
Iterator it3 = myEmp.getSalarieses().iterator();
Iterator it4 = myEmp.getDeptEmps().iterator();
}
Entity and References - the Lazy Factor
Lazy SQL
Hibernate: select ... from employees.employees employeess0_ where emp_no>10000 and emp_no<20020
19/05/15 16:34:57 INFO [PL20192]: EmployeeSummary name = Georgi Fucelli
Hibernate: select ... from employees.titles titleses0_ where titleses0_.emp_no=?
Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=?
Hibernate: select ... from employees.dept_emp deptemps0_ where deptemps0_.emp_no=?
19/05/15 16:35:06 INFO [PL20192]: EmployeeSummary name = Bezalel Simmel
Not Lazy SQL
Hibernate: select ... from employees.employees employeess0_ where emp_no>10000 and emp_no<10003
Hibernate: select ... from employees.dept_manager deptmanage0_ where deptmanage0_.emp_no=?
Hibernate: select ... from employees.dept_emp deptemps0_ where deptemps0_.emp_no=?
Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=?
Hibernate: select ... from employees.titles titleses0_ where titleses0_.emp_no=?
Hibernate: select ... from employees.dept_manager deptmanage0_ where deptmanage0_.emp_no=?
Hibernate: select ... from employees.dept_emp deptemps0_ where deptemps0_.emp_no=?
Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=?
Hibernate: select ... from employees.titles titleses0_ where titleses0_.emp_no=?
19/05/15 16:40:54 INFO [PL20192]: EmployeeSummary name = Georgi Fucelli
19/05/15 16:41:01 INFO [PL20192]: EmployeeSummary name = Bezalel Simmel
4
0
Entity and References - the Lazy Factor
4
1
Entity and References - the Lazy Factor
Best way to handle it … and be safe.
4
2
Entity and References - the Lazy Factor
Best way to handle it … and be safe. WAIT
WAIT
WAIT
WHY FKs???
DBA HR Complains
Your application has overwritten HR data
● Data out of order
● Missing consistency
● Unexpected results
4
4
Lock Me Please
TRX 1
logger.info("I am the 1st TRX ");
EmployeesSummary myEmp =
se.find(EmployeesSummary.class,10001,
LockModeType.PESSIMISTIC_WRITE);
Set salaries = null;
salaries = myEmp.getSalarieses();
Iterator itS = salaries.iterator();
while(itS.hasNext()) {
Salaries mySal = (Salaries) itS.next();
if(mySal.getToDate().toString().equals("9999-01-01")){
logger.info("1TRX Employee name Before = "
+ myEmp.getFirstName()+" "
+ myEmp.getLastName()
+" " + mySal.getSalary());
mySal.setSalary(mySal.getSalary() + 1000);
logger.info("1TRX Employee name After = "
+ myEmp.getFirstName()+" "
+ myEmp.getLastName() +" " + mySal.getSalary());
}
}
logger.info("Another Transaction is modifying the same value ");
se.saveOrUpdate(myEmp);
se.getTransaction().commit();
se.disconnect();
se.close();
logger.info("1TRX COmplete");
TRX 2
logger.info("I am the 2nd TRX ");
EmployeesSummary myEmp = se.find(EmployeesSummary.class,10001);
Set salaries = null;
salaries = myEmp.getSalarieses();
Iterator itS = salaries.iterator();
while(itS.hasNext()) {
Salaries mySal = (Salaries) itS.next();
if(mySal.getToDate().toString().equals("9999-01-01")){
logger.info("2TRX Employee name Before = "
+ myEmp.getFirstName()+" "
+ myEmp.getLastName() +" "
+ mySal.getSalary());
mySal.setSalary(mySal.getSalary() - 400);
logger.info("2TRX Employee name After = "
+ myEmp.getFirstName()+" "
+ myEmp.getLastName() +" "
+ mySal.getSalary());
}
}
se.saveOrUpdate(myEmp);
se.getTransaction().commit();
se.disconnect();
se.close();
logger.info("2TRX COmplete");
4
5
Lock Me Please
4
6
Lock Me Please
I am the 1st TRX
Hibernate: select ... from employees.employees employees0_ where employees0_.emp_no=? for update
Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=?
Hibernate: update employees.salaries set salary=?, to_date=? where emp_no=? and from_date=?
I am the 2nd TRX
Hibernate: select ... from employees.employees employees0_ where employees0_.emp_no=?
Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=?
Hibernate: update employees.salaries set salary=?, to_date=? where emp_no=? and from_date=?
4
7
Lock Me Please - WHY?
Because the select for update is on the main object -> Employees, but I am actually updating a Salaries
record so ... no lock
Hibernate: select employees0_.emp_no as emp_no1_3_0_... from employees.employees employees0_
where employees0_.emp_no=? for update
If using lock also on the second TRX
19/05/14 12:16:57 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper2]: Lock wait timeout
exceeded; try restarting transaction
Exception in thread "main" javax.persistence.PessimisticLockException: could not extract ResultSet
The right thing to do?
- If you want to operate by parent object be sure you lock them also in the other TRX
- DO NOT operate by parent and instead operate by sub (Salaries) and be sure to lock it
4
8
A Can of Worms
This is actually even more complicated, and a real...
5
0
What Can We Do Better?
A few thing to keep in mind:
● Select by pager (yes you can do it)
● Use reduced object when you don't need all columns (use different classes)
● Use Lazy
● Use LockModeType.PESSIMISTIC_WRITE only when needed, but use it
● Use high JDBC fetch size in Hibernate conf
● Leave sequence to DB
● Do not detach / attach entities lightly
● Release connection after transaction
● Use connection Pool with Hibernate
● Do not use Hibernate unless you really need to
● Apply JDBC optimizations
Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice Versa
Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice Versa
Thank You to Our Sponsors
5
5
Rate My Session

More Related Content

PDF
PDF
Introduction to JPA and Hibernate including examples
PPT
jpa-hibernate-presentation
PDF
JPA and Hibernate
PPT
Hibernate Tutorial
PPTX
Introduction to JPA (JPA version 2.0)
PPTX
Modular javascript
PPTX
Sqladria 2009 SRC
Introduction to JPA and Hibernate including examples
jpa-hibernate-presentation
JPA and Hibernate
Hibernate Tutorial
Introduction to JPA (JPA version 2.0)
Modular javascript
Sqladria 2009 SRC

What's hot (20)

PPT
Introduction to hibernate
PPTX
1. java database connectivity (jdbc)
PPT
java jdbc connection
PPT
Jdbc sasidhar
PPTX
Schema webinar
PPT
hibernate with JPA
PPT
JDBC – Java Database Connectivity
PPTX
Schema201 webinar
KEY
Data perisistence in iOS
PDF
ScalikeJDBC Tutorial for Beginners
PPT
Entity Persistence with JPA
PPTX
Jpa 2.1 Application Development
PPT
3 database-jdbc(1)
ODP
JPA Best Practices
DOCX
Library system project file
PPS
Jdbc api
PPTX
JDBC ppt
DOCX
Ktifkan dulu microsoft visual basic
PPSX
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Introduction to hibernate
1. java database connectivity (jdbc)
java jdbc connection
Jdbc sasidhar
Schema webinar
hibernate with JPA
JDBC – Java Database Connectivity
Schema201 webinar
Data perisistence in iOS
ScalikeJDBC Tutorial for Beginners
Entity Persistence with JPA
Jpa 2.1 Application Development
3 database-jdbc(1)
JPA Best Practices
Library system project file
Jdbc api
JDBC ppt
Ktifkan dulu microsoft visual basic
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Ad

Similar to Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice Versa (20)

PPT
Hibernate jj
PDF
Hibernate 3
PPTX
Hibernate tutorial
PPTX
Module-3 for career and JFSD ppt for study.pptx
PPT
PPTX
Hibernate
PPTX
Hibernate
PPT
High Performance Jdbc
PPTX
Hibernate in XPages
PDF
Free Hibernate Tutorial | VirtualNuggets
PDF
JDBC in Servlets
PPTX
Hibernate in Action
PPS
Java Hibernate Programming with Architecture Diagram and Example
PPT
What is hibernate?
DOC
Hibernate tutorial for beginners
PPT
Hibernate training-topics
PDF
Advance Features of Hibernate
PPTX
SeaJUG May 2012 mybatis
PPT
Basic Hibernate Final
PDF
What is hibernate?
Hibernate jj
Hibernate 3
Hibernate tutorial
Module-3 for career and JFSD ppt for study.pptx
Hibernate
Hibernate
High Performance Jdbc
Hibernate in XPages
Free Hibernate Tutorial | VirtualNuggets
JDBC in Servlets
Hibernate in Action
Java Hibernate Programming with Architecture Diagram and Example
What is hibernate?
Hibernate tutorial for beginners
Hibernate training-topics
Advance Features of Hibernate
SeaJUG May 2012 mybatis
Basic Hibernate Final
What is hibernate?
Ad

More from Marco Tusa (20)

PDF
Percona xtra db cluster(pxc) non blocking operations, what you need to know t...
PDF
My sql on kubernetes demystified
PDF
Comparing high availability solutions with percona xtradb cluster and percona...
PDF
Accessing data through hibernate: what DBAs should tell to developers and vic...
PDF
Best practice-high availability-solution-geo-distributed-final
PDF
MySQL innoDB split and merge pages
PDF
Robust ha solutions with proxysql
PDF
Fortify aws aurora_proxy_2019_pleu
PDF
Are we there Yet?? (The long journey of Migrating from close source to opens...
PPTX
Improve aws withproxysql
PDF
Fortify aws aurora_proxy
PDF
Mysql8 advance tuning with resource group
PDF
Proxysql sharding
PDF
Geographically dispersed perconaxtra db cluster deployment
PDF
Sync rep aurora_2016
PDF
Proxysql ha plam_2016_2_keynote
PPT
Empower my sql server administration with 5.7 instruments
PDF
Galera explained 3
PDF
Plmce 14 be a_hero_16x9_final
PDF
Scaling with sync_replication using Galera and EC2
Percona xtra db cluster(pxc) non blocking operations, what you need to know t...
My sql on kubernetes demystified
Comparing high availability solutions with percona xtradb cluster and percona...
Accessing data through hibernate: what DBAs should tell to developers and vic...
Best practice-high availability-solution-geo-distributed-final
MySQL innoDB split and merge pages
Robust ha solutions with proxysql
Fortify aws aurora_proxy_2019_pleu
Are we there Yet?? (The long journey of Migrating from close source to opens...
Improve aws withproxysql
Fortify aws aurora_proxy
Mysql8 advance tuning with resource group
Proxysql sharding
Geographically dispersed perconaxtra db cluster deployment
Sync rep aurora_2016
Proxysql ha plam_2016_2_keynote
Empower my sql server administration with 5.7 instruments
Galera explained 3
Plmce 14 be a_hero_16x9_final
Scaling with sync_replication using Galera and EC2

Recently uploaded (20)

PPTX
Emphasizing It's Not The End 08 06 2025.pptx
PPTX
fundraisepro pitch deck elegant and modern
PDF
Presentation1 [Autosaved].pdf diagnosiss
PPTX
Relationship Management Presentation In Banking.pptx
PDF
Instagram's Product Secrets Unveiled with this PPT
PPT
First Aid Training Presentation Slides.ppt
PPTX
Project and change Managment: short video sequences for IBA
PPTX
Presentation for DGJV QMS (PQP)_12.03.2025.pptx
PPTX
Anesthesia and it's stage with mnemonic and images
PPT
The Effect of Human Resource Management Practice on Organizational Performanc...
PPTX
Tablets And Capsule Preformulation Of Paracetamol
PPTX
Tour Presentation Educational Activity.pptx
DOC
学位双硕士UTAS毕业证,墨尔本理工学院毕业证留学硕士毕业证
PPTX
_ISO_Presentation_ISO 9001 and 45001.pptx
PPTX
Primary and secondary sources, and history
PPTX
chapter8-180915055454bycuufucdghrwtrt.pptx
PPTX
nose tajweed for the arabic alphabets for the responsive
PPTX
Self management and self evaluation presentation
PPTX
Introduction-to-Food-Packaging-and-packaging -materials.pptx
PPTX
PHIL.-ASTRONOMY-AND-NAVIGATION of ..pptx
Emphasizing It's Not The End 08 06 2025.pptx
fundraisepro pitch deck elegant and modern
Presentation1 [Autosaved].pdf diagnosiss
Relationship Management Presentation In Banking.pptx
Instagram's Product Secrets Unveiled with this PPT
First Aid Training Presentation Slides.ppt
Project and change Managment: short video sequences for IBA
Presentation for DGJV QMS (PQP)_12.03.2025.pptx
Anesthesia and it's stage with mnemonic and images
The Effect of Human Resource Management Practice on Organizational Performanc...
Tablets And Capsule Preformulation Of Paracetamol
Tour Presentation Educational Activity.pptx
学位双硕士UTAS毕业证,墨尔本理工学院毕业证留学硕士毕业证
_ISO_Presentation_ISO 9001 and 45001.pptx
Primary and secondary sources, and history
chapter8-180915055454bycuufucdghrwtrt.pptx
nose tajweed for the arabic alphabets for the responsive
Self management and self evaluation presentation
Introduction-to-Food-Packaging-and-packaging -materials.pptx
PHIL.-ASTRONOMY-AND-NAVIGATION of ..pptx

Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice Versa

  • 1. Accessing Data Through Hibernate; What DBAs Should Tell Developers and Vice Versa Marco Tusa and Francisco Bordenave Percona
  • 3. 3 Agenda 1. Basic description of Hibernate architecture 2. Basic description of MySQl architecture 3. What is an Object entity in Hibernate? 4. What it means for a DB? 5. JDBC 6. Simple example with One table (employees) as object 7. What it is employees as DB object? 8. CRUD example with SQL generation 9. What is the overhead in using Hibernate? 10.What is a composite object and what is the impact? 11.Can we do better?
  • 4. 4 Introduction / Disclaimer the important … is to have clear ideas and coordinated direction What is this fish? I didn’t ask for sushi Java? Why is he talking about coffee, I ordered sushi!
  • 5. 5 Hibernate Basic Architecture Benefit from developer’s point of view: ● Object-relational mapping (ORM) ● Makes it easy to access data ● Rows become objects ● Don’t have to deal with how data is accessed ● Data persist in the application after query ● I can access multiple sources with same logic/code In short my life is easier without dealing with SQL
  • 6. 6 DBA Let’s see a very high level and basic description of internals
  • 9. 9 DBA Now being serious MySQL is the RDBMS InnoDB is the engine Data is organized in 16kb pages Clustered Primary Key and then secondary indexes
  • 10. 1 0 DBA Now being serious MySQL is the RDBMS InnoDB is the engine Data is organized in 16kb pages Clustered Primary Key and then secondary indexes InnoDB supports transactions (i.e. BEGIN/COMMIT) and has ACID capabilities: ● Atomicity ● Consistency ● Isolation ● Durability Isolation means transactions should not affect other transactions when running concurrently.
  • 11. 1 1 Data Access Using Hibernate ● So I have a DB ● My code ● JDBC ● Hibernate If I have Hibernate why I need to know all these additional things? I just need: ● Hibernate SessionFactory (heavy to create and one for Application or by data store) ● Hibernate Session, light, ephemeral, Open-close it inside nuclear operations
  • 12. 1 2 What is an Entity? And States? I need to know that I have this:
  • 13. 1 3 Simple example with One table employees ● Mapping definition ● Code What is an Entity? <hibernate-mapping package="net.tc.employees"> <class name="Employees" table="employees" catalog="employees" optimistic-lock="version"> <id name="empNo" type="int"> <column name="emp_no" /> <generator class="assigned" /> </id> <property name="birthDate" type="date" > <column name="birth_date" length="10" not-null="true" /> <property name="firstName" type="string" > <column name="first_name" length="14" not-null="true" /> public class Employees implements java.io.Serializable { private int empNo; private Date birthDate; private String firstName; private String lastName; private char gender; private Date hireDate; private Set titleses = new HashSet(0); private Set salarieses = new HashSet(0); private Set deptEmps = new HashSet(0); private Set deptManagers = new HashSet(0); public Employees() { } public Employees(int empNo, Date birthDate, String firstName, String lastName, char gender, Date hireDate) { this.empNo = empNo; this.birthDate = birthDate; this.firstName = firstName; this.lastName = lastName; this.gender = gender; this.hireDate = hireDate; }
  • 14. DBA So what’s an entity in relational database?
  • 15. DBA So what is an entity in a relational database? Simple: it is a row in the table show create table employeesG *************************** 1. row *************************** Table: employees Create Table: CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NOT NULL, `first_name` varchar(14) NOT NULL, `last_name` varchar(16) NOT NULL, `gender` enum('M','F') NOT NULL, `hire_date` date NOT NULL, PRIMARY KEY (`emp_no`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.01 sec) show create table salariesG *************************** 1. row *************************** Table: salaries Create Table: CREATE TABLE `salaries` ( `emp_no` int(11) NOT NULL, `salary` int(11) NOT NULL, `from_date` date NOT NULL, `to_date` date NOT NULL, PRIMARY KEY (`emp_no`,`from_date`), KEY `emp_no` (`emp_no`), CONSTRAINT `salaries_ibfk_1` FOREIGN KEY (`emp_no`) REFERENCES `employees` (`emp_no`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
  • 16. 1 6 Connection Pool + JDBC Pollution Connections: Important to know that a connection=thread in MySQL. Thread allocates buffers (tmp_table_size, sort_buffer_size, etc) --> Thread = CPU and Memory work. The more the threads, the more the CPU and Memory pressure.
  • 17. 1 7 Connection Pool + JDBC Pollution Connections: Inside MySQL 2 ways of handling threads (thread_handling variable): - 1 thread per each connection - one-thread-per-connection (thread_cache_size) - pool of threads - loaded_dinamically (thread_pool_size) - Enterprise feature - Percona Server has a thread pool library pool-of-threads Rule of thumb: - In MySQL most of use cases are handled properly with one_thread_per_connection - Thread pool fits only in few use cases: normally high number of threads running very short queries.
  • 18. 1 8 Connection Pool + JDBC Pollution Connections Out of MySQL JDBC - API for connecting to MySQL from Java App - Several connection pool handlers - Hikari -> standard nowadays - c3p0 (still common but no longer recommended)
  • 19. 1 9 Connection Pool + JDBC Pollution Connection Pool: Connection pool as external concept VS internal Connection pool In MySQL: group of connections (threads) constantly opened and re used. Out of MySQL: group of connections handled by framework which may or not be kept opened. JDBC pollution (a.k.a. damn defaults): Simple connection without optimization /* mysql-connector-java-8.0.12 (Revision: 24766725dc6e017025532146d94c6e6c488fb8f1) */SELECT @@session.auto_increment_increment AS auto_increment_increment, @@character_set_client AS character_set_client, @@character_set_connection AS character_set_connection, @@character_set_results AS character_set_results, @@character_set_server AS character_set_server, @@collation_server AS collation_server, @@init_connect AS init_connect, @@interactive_timeout AS interactive_timeout, @@license AS license, @@lower_case_table_names AS lower_case_table_names, @@max_allowed_packet AS max_allowed_packet, @@net_write_timeout AS net_write_timeout, @@query_cache_size AS query_cache_size, @@query_cache_type AS query_cache_type, @@sql_mode AS sql_mode, @@system_time_zone AS system_time_zone, @@time_zone AS time_zone, @@transaction_isolation AS transaction_isolation, @@wait_timeout AS wait_timeout;
  • 20. 2 0 Connection Pool + JDBC Pollution Noise exists, but can be reduced: hibernate.hikari.dataSource.cachePrepStmts">true hibernate.hikari.dataSource.defaultFetchSize">100 hibernate.hikari.dataSource.prepStmtCacheSize">250 hibernate.hikari.dataSource.prepStmtCacheSqlLimit">2048 hibernate.hikari.dataSource.useServerPrepStmts">true hibernate.hikari.dataSource.useLocalSessionState">true hibernate.hikari.dataSource.rewriteBatchedStatements">true hibernate.hikari.dataSource.cacheResultSetMetadata">true hibernate.hikari.dataSource.cacheServerConfiguration">true hibernate.hikari.dataSource.elideSetAutoCommits">true hibernate.hikari.dataSource.maintainTimeStats">false For Hibernate you must add in URL jdbc:mysql://127.0.0.1:3306/employees?prepStmtCacheSize=250&am p;prepStmtCacheSqlLimit=2048&amp;useServerPrepStmts=YES&amp;us eLocalSessionState=YES&amp;useSSL=false&amp;defaultFetchSize=1 00&amp;rewriteBatchedStatements=YES&amp;cacheResultSetMetadata =YES&amp;cacheServerConfiguration=YES&amp;elideSetAutoCommits= YES&amp;maintainTimeStats=false
  • 21. Now For Some More Insight
  • 22. 2 2 Developer CRUD Code Hibernate Insert Session se = sessionFactoryEmp2.openSession(); se.setJdbcBatchSize(1); se.beginTransaction(); int i=1; while(++i < 500) { Employees employee = new Employees(); employee.setBirthDate(new Date()); employee.setHireDate(new Date()); employee.setGender('M'); employee.setEmpNo(i); employee.setFirstName("Franco" + 1); employee.setLastName("Castagna"+i); se.save(employee); } se.getTransaction().commit(); se.close(); Read Session se = sessionFactoryEmp2.openSession(); se.setJdbcBatchSize(1); se.beginTransaction(); List<Employees> employees = se.createQuery("from Employees where emp_no <999 " ).list(); se.disconnect(); se.close(); Update se.beginTransaction(); List<Employees> employees = se.createQuery("from Employees where emp_no <999 " ).list(); int i = 0; Iterator it = employees.iterator(); while(it.hasNext()) { Employees myEmp = (Employees) it.next(); try{myEmp.setHireDate(this.getSimpleDateFormat().parse("2015-"+ getRandomNumberInRange(1,12) +"-10"));}catch(Exception ae ) {ae.printStackTrace();} se.update(myEmp); } se.getTransaction().commit(); se.disconnect(); se.close();
  • 23. 2 3 Developer CRUD Code Simple Code No Batch Insert Statement stmt = conn.createStatement(); int i=0; StringBuffer sb =new StringBuffer(); String sqlHead="INSERT INTO employees (emp_no,birth_date,first_name,last_name,gender,hire_date) VALUES ("; stmt.execute("START TRANSACTION"); while(++i < 500) { sb.append(i); sb.append(",’”+ this.getSimpleDateFormat().format(new Date()) +"'"); sb.append(",'Franco"+ i +"'"); sb.append(",'Castagna"+ i +"'"); sb.append(",'M'"); sb.append(",’”+ this.getSimpleDateFormat().format(new Date()) +"'"); sb.append(")"); stmt.execute(sqlHead+sb.toString()); sb.delete(0,sb.length()); } conn.commit(); Read StringBuffer sb =new StringBuffer(); String sqlHead="SELECT emp_no,birth_date,first_name,last_name,gender,hire_date FROM employees where emp_no="; int rowReturned=0; while(++i < 500) { sb.append(i); ResultSet rs = stmt.executeQuery(sqlHead+sb.toString()); HashSet employees = new HashSet(); while(rs.next()) { Employees employee = new Employees(); employee.setBirthDate(rs.getDate("birth_date")); employee.setHireDate(rs.getDate("hire_date")); employee.setGender( rs.getString("gender").charAt(0)); employee.setEmpNo(rs.getInt("emp_no")); employee.setFirstName(rs.getString("first_name")); employee.setLastName(rs.getString("last_name")); employees.add(employee); } } Delete Statement stmt = conn.createStatement(); int i=0; String sqlHead="Delete from employees where emp_no="; stmt.execute("START TRANSACTION"); while(++i < 500) { stmt.execute(sqlHead+i); } conn.commit();
  • 24. DBA Where is the overhead in: - Additional not useful SQL - too many temporary tables on disk - causes IO overhead - Duplicated SQL - too many show/set commands - causes CPU/Memory overhead - Not optimized SQL (like batching and so on) - Queries coming from framework are generally not properly optimized - Poorly optimized queries hit everything: CPU/Memory/IO
  • 25. Evidence Hibernate # Time: 2019-05-14T11:27:20.481014Z # User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1919 # Query_time: 0.000008 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 SET timestamp=1557833240; # administrator command: Close stmt; # Time: 2019-05-14T11:27:20.481484Z # User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1919 # Query_time: 0.000059 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 SET timestamp=1557833240; # administrator command: Prepare; # Time: 2019-05-14T11:27:20.482054Z # User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1919 # Query_time: 0.000091 Lock_time: 0.000029 Rows_sent: 0 Rows_examined: 0 SET timestamp=1557833240; insert into employees.employees (birth_date, first_name, last_name, gender, hire_date, emp_no) values ('2019-05-14', 'Franco1', 'Castagna2', 'M', '2019-05-14', 2);
  • 26. Evidence Standard call/code SET timestamp=1557833376; INSERT INTO employees (emp_no,birth_date,first_name,last_name,gender,hire_date) VALUES (1,'2019-05-14','Franco1','Castagna1','M','2019-05-14'); # Time: 2019-05-14T11:29:36.974274Z # User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1934 # Query_time: 0.000082 Lock_time: 0.000033 Rows_sent: 0 Rows_examined: 0 SET timestamp=1557833376; INSERT INTO employees (emp_no,birth_date,first_name,last_name,gender,hire_date) VALUES (2,'2019-05-14','Franco2','Castagna2','M','2019-05-14');
  • 27. 2 7 Developer - CRUD Results No Batch
  • 28. What Can Be Done? - Batch Hibernate configuration <hibernate-configuration> <session-factory > <property name="sessionFactoryName">Hikari</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.jdbc.batch_size">20</property> Java code Hibernate related Session se = sessionFactoryEmp2.openSession(); se.setJdbcBatchSize(20); se.beginTransaction(); while(i < 500) { Employees employee = new Employees(); employee.setBirthDate(new Date()); ... se.save(employee); if ( ++i % 20 == 0 ) { //20, same as the JDBC batch sizeflush a batch of inserts and release memory: se.flush(); se.clear(); } }
  • 29. What Can Be Done? - Batch Hibernate SET timestamp=1557833655; insert into employees.employees (birth_date, first_name, last_name, gender, hire_date, emp_no) values ('2019-05-14', 'Franco1', 'Castagna1', 'M', '2019-05-14', 1),...,('2019-05-14', 'Franco1', 'Castagna19', 'M', '2019-05-14', 19); # Time: 2019-05-14T11:34:15.998326Z # User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1945 # Query_time: 0.000024 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 SET timestamp=1557833655; # administrator command: Close stmt; # Time: 2019-05-14T11:34:15.998609Z # User@Host: hibernatee[hibernatee] @ [127.0.0.1] Id: 1945 # Query_time: 0.000008 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
  • 30. 3 0 Developer - CRUD Results With Batch
  • 31. 3 1 CRUD Summary With Optimization
  • 32. DBA - What is That Traffic? ● A lot of data is read from the DB over and over ● Tons of simple queries ● Queries involves also referenced tables and not only the main one
  • 33. 3 3 Developer - Entity and References
  • 34. 3 4 Developer Entity and References Let us start with the cool things: Session se = sessionFactoryEmp2.openSession(); se.beginTransaction(); Employees myEmp = se.find(Employees.class,10001, LockModeType.PESSIMISTIC_WRITE); Set salaries = null; salaries = myEmp.getSalarieses(); Iterator itS = salaries.iterator(); while(itS.hasNext()) { Salaries mySal = (Salaries) itS.next(); if(mySal.getToDate().toString().equals("9999-01-01")){ mySal.setSalary(mySal.getSalary() + 100); } } se.saveOrUpdate(myEmp); se.getTransaction().commit(); se.disconnect(); se.close(); Performance ALERT
  • 35. 3 5 Developer Entity and References Employees myEmp = se.find(Employees.class,10001, LockModeType.PESSIMISTIC_WRITE); ● Hibernate: select employees0_.emp_no as emp_no1_3_0_... from employees.employees employees0_ where employees0_.emp_no=? for update salaries = myEmp.getSalarieses(); ● Hibernate: select salarieses0_.emp_no as emp_no1_4_0_... from employees.salaries salarieses0_ where salarieses0_.emp_no=? se.saveOrUpdate(myEmp); ● Hibernate: update employees.salaries set salary=?, to_date=? where emp_no=? and from_date=?
  • 36. 3 6 Developer Entity and References ● Entities and sets (References) ● Great to have them (sets) but sometime they stab you in the back! ● What is Lazy and how to control it ... if you can! ● A few tests will follow: ○ Get (select) Employees Lazy/Not Lazy Hibernate versus simple code ○ Update a Salary value for a given employee
  • 37. 3 7 Entity and references the Lazy factor Remember this?
  • 38. Entity and References - the Lazy Factor <set name="salarieses" table="salaries" lazy="true|false" fetch="select" > <key> <column name="emp_no" not-null="true" /> </key> <one-to-many class="net.tc.employees.Salaries"/> </set> LAZY List<Employees> employees = se.createQuery("from EmployeesSummary where emp_no >10000 and emp_no < 20020 " ).list(); Iterator it = employees.iterator(); while(it.hasNext()) { Employees myEmp = (Employees) it.next(); logger.info("EmployeeSummary name = " + myEmp.getFirstName()+" "+ myEmp.getLastName()); Iterator it2 = myEmp.getTitleses().iterator(); ← HERE I retrieve the info Iterator it3 = myEmp.getSalarieses().iterator(); ← HERE I retrieve the info Iterator it4 = myEmp.getDeptEmps().iterator(); ← HERE I retrieve the info } NOT LAZY List<Employees> employees = se.createQuery("from EmployeesSummary where emp_no >10000 and emp_no < 20020 " ).list(); ← HERE Iterator it = employees.iterator(); while(it.hasNext()) { Employees myEmp = (Employees) it.next(); logger.info("EmployeeSummary name = " + myEmp.getFirstName()+" "+ myEmp.getLastName()); Iterator it2 = myEmp.getTitleses().iterator(); Iterator it3 = myEmp.getSalarieses().iterator(); Iterator it4 = myEmp.getDeptEmps().iterator(); }
  • 39. Entity and References - the Lazy Factor Lazy SQL Hibernate: select ... from employees.employees employeess0_ where emp_no>10000 and emp_no<20020 19/05/15 16:34:57 INFO [PL20192]: EmployeeSummary name = Georgi Fucelli Hibernate: select ... from employees.titles titleses0_ where titleses0_.emp_no=? Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=? Hibernate: select ... from employees.dept_emp deptemps0_ where deptemps0_.emp_no=? 19/05/15 16:35:06 INFO [PL20192]: EmployeeSummary name = Bezalel Simmel Not Lazy SQL Hibernate: select ... from employees.employees employeess0_ where emp_no>10000 and emp_no<10003 Hibernate: select ... from employees.dept_manager deptmanage0_ where deptmanage0_.emp_no=? Hibernate: select ... from employees.dept_emp deptemps0_ where deptemps0_.emp_no=? Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=? Hibernate: select ... from employees.titles titleses0_ where titleses0_.emp_no=? Hibernate: select ... from employees.dept_manager deptmanage0_ where deptmanage0_.emp_no=? Hibernate: select ... from employees.dept_emp deptemps0_ where deptemps0_.emp_no=? Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=? Hibernate: select ... from employees.titles titleses0_ where titleses0_.emp_no=? 19/05/15 16:40:54 INFO [PL20192]: EmployeeSummary name = Georgi Fucelli 19/05/15 16:41:01 INFO [PL20192]: EmployeeSummary name = Bezalel Simmel
  • 40. 4 0 Entity and References - the Lazy Factor
  • 41. 4 1 Entity and References - the Lazy Factor Best way to handle it … and be safe.
  • 42. 4 2 Entity and References - the Lazy Factor Best way to handle it … and be safe. WAIT WAIT WAIT WHY FKs???
  • 43. DBA HR Complains Your application has overwritten HR data ● Data out of order ● Missing consistency ● Unexpected results
  • 44. 4 4 Lock Me Please TRX 1 logger.info("I am the 1st TRX "); EmployeesSummary myEmp = se.find(EmployeesSummary.class,10001, LockModeType.PESSIMISTIC_WRITE); Set salaries = null; salaries = myEmp.getSalarieses(); Iterator itS = salaries.iterator(); while(itS.hasNext()) { Salaries mySal = (Salaries) itS.next(); if(mySal.getToDate().toString().equals("9999-01-01")){ logger.info("1TRX Employee name Before = " + myEmp.getFirstName()+" " + myEmp.getLastName() +" " + mySal.getSalary()); mySal.setSalary(mySal.getSalary() + 1000); logger.info("1TRX Employee name After = " + myEmp.getFirstName()+" " + myEmp.getLastName() +" " + mySal.getSalary()); } } logger.info("Another Transaction is modifying the same value "); se.saveOrUpdate(myEmp); se.getTransaction().commit(); se.disconnect(); se.close(); logger.info("1TRX COmplete"); TRX 2 logger.info("I am the 2nd TRX "); EmployeesSummary myEmp = se.find(EmployeesSummary.class,10001); Set salaries = null; salaries = myEmp.getSalarieses(); Iterator itS = salaries.iterator(); while(itS.hasNext()) { Salaries mySal = (Salaries) itS.next(); if(mySal.getToDate().toString().equals("9999-01-01")){ logger.info("2TRX Employee name Before = " + myEmp.getFirstName()+" " + myEmp.getLastName() +" " + mySal.getSalary()); mySal.setSalary(mySal.getSalary() - 400); logger.info("2TRX Employee name After = " + myEmp.getFirstName()+" " + myEmp.getLastName() +" " + mySal.getSalary()); } } se.saveOrUpdate(myEmp); se.getTransaction().commit(); se.disconnect(); se.close(); logger.info("2TRX COmplete");
  • 46. 4 6 Lock Me Please I am the 1st TRX Hibernate: select ... from employees.employees employees0_ where employees0_.emp_no=? for update Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=? Hibernate: update employees.salaries set salary=?, to_date=? where emp_no=? and from_date=? I am the 2nd TRX Hibernate: select ... from employees.employees employees0_ where employees0_.emp_no=? Hibernate: select ... from employees.salaries salarieses0_ where salarieses0_.emp_no=? Hibernate: update employees.salaries set salary=?, to_date=? where emp_no=? and from_date=?
  • 47. 4 7 Lock Me Please - WHY? Because the select for update is on the main object -> Employees, but I am actually updating a Salaries record so ... no lock Hibernate: select employees0_.emp_no as emp_no1_3_0_... from employees.employees employees0_ where employees0_.emp_no=? for update If using lock also on the second TRX 19/05/14 12:16:57 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper2]: Lock wait timeout exceeded; try restarting transaction Exception in thread "main" javax.persistence.PessimisticLockException: could not extract ResultSet The right thing to do? - If you want to operate by parent object be sure you lock them also in the other TRX - DO NOT operate by parent and instead operate by sub (Salaries) and be sure to lock it
  • 48. 4 8 A Can of Worms This is actually even more complicated, and a real...
  • 49. 5 0 What Can We Do Better? A few thing to keep in mind: ● Select by pager (yes you can do it) ● Use reduced object when you don't need all columns (use different classes) ● Use Lazy ● Use LockModeType.PESSIMISTIC_WRITE only when needed, but use it ● Use high JDBC fetch size in Hibernate conf ● Leave sequence to DB ● Do not detach / attach entities lightly ● Release connection after transaction ● Use connection Pool with Hibernate ● Do not use Hibernate unless you really need to ● Apply JDBC optimizations
  • 52. Thank You to Our Sponsors