SlideShare a Scribd company logo
1 of 173
Download to read offline
Hibernate EFETIVO 
ERROS COMUNS E SOLUÇÕES 
Rafael Ponte 
COALTI-2014 / ALJUG
Eu estava me 
perguntando quando de 
fato o Hibernate foi 
criado...
Eu estava me 
perguntando quando de 
fato o Hibernate foi 
criado... 
Luca Bastos 
O “Boom” foi em 2003!
Mais de uma década! 
2014 - 2003 = 11
mas ainda hoje...
mas ainda hoje... 
existem devs que 
subutilizam o framework
mas ainda hoje... 
existem devs que 
subutilizam o framework 
problemas de perfomance 
e escalabilidade
e pra piorar...
culpam o Hibernate
culpam o Hibernate 
A culpa é do Banco de 
Dados! 
Sérgio
é fácil culpar o que não se 
conhece...
um SGDB mal configurado 
pode ser o problema...
um SGDB mal configurado 
pode ser o problema... 
MAS na maioria das vezes o 
problema está na SUA 
APLICAÇÃO
tabelas sem índices 
<3
tabelas sem índices 
consultas mal-feitas 
<3 <3
tabelas sem índices 
consultas mal-feitas 
<3 <3 <3 
muitos hits ao banco
tabelas sem índices 
consultas mal-feitas 
muitos hits ao banco 
connection leaks 
<3 <3 <3
tabelas sem índices 
consultas mal-feitas 
muitos hits ao banco 
connection leaks 
<3 <3 <3 
memory leaks
Não saber tirar 
proveito framework
Hibernate Efetivo 
6 dicas para não deixar 
sua app morrer
@rponte
Fortaleza - Terra do Sol
Miguel Lima
#1 
POOL DE 
CONEXÕES
com certeza todos aqui 
já ouviram falar...
mas nem todos dão a devida atenção...
mas nem todos dão a devida atenção... 
até perceberem a app engasgando
mas nem todos dão a devida atenção... 
até perceberem a app engasgando 
ou até receberem um
mas nem todos dão a devida atenção... 
até perceberem a app engasgando 
ou até receberem um 
org.hibernate.exception.Gener 
icJDBCException: Cannot 
open connection
daí percebem que não configuraram o 
o pool do Hibernate 
hibernate.properties 
hibernate.connection.driver_class=org.postgresql.Driver 
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect 
hibernate.connection.url=jdbc:postgresql://localhost:5432/myapp 
hibernate.connection.username=postgres 
hibernate.connection.password=1234 
! 
! 
!
daí percebem que não configuraram o 
o pool do Hibernate 
hibernate.properties 
hibernate.connection.driver_class=org.postgresql.Driver 
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect 
hibernate.connection.url=jdbc:postgresql://localhost:5432/myapp 
hibernate.connection.username=postgres 
hibernate.connection.password=1234 
hibernate.connection.pool_size=30 
! 
!
daí percebem que não configuraram o 
o pool do Hibernate 
hibernate.properties 
hibernate.connection.driver_class=org.postgresql.Driver 
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect 
hibernate.connection.url=jdbc:postgresql://localhost:5432/myapp 
hibernate.connection.username=postgres 
hibernate.connection.password=1234 
hibernate.connection.pool_size=30 
! 
!
a app volta a funcionar 
bem por um tempo
a app volta a funcionar 
bem por um tempo
e vão alocando mais conexões com o 
tempo 
hibernate.properties 
hibernate.connection.pool_size=30 
40 
55 
70 
...
o pool PADRÃO do 
Hibernate
que possui uma impl. 
RUDIMENTAR
INFO DriverManagerConnectionProvider:64 - Using Hibernate built-in 
connection pool (not for production use!)! 
INFO DriverManagerConnectionProvider:65 - Hibernate connection pool 
size: 20!
not for production use! 
INFO DriverManagerConnectionProvider:64 - Using Hibernate built-in 
connection pool (not for production use!)! 
INFO DriverManagerConnectionProvider:65 - Hibernate connection pool 
size: 20!
qual pool utilizar?
temos ótimas opções...
temos ótimas opções... 
pools como c3p0 ou 
commons-dbcp
o Hibernate já vem 
com c3p0
configurando c3p0 
hibernate.properties 
hibernate.connection.driver_class=org.postgresql.Driver 
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect 
hibernate.connection.url=jdbc:postgresql://localhost:5432/myapp 
hibernate.connection.username=postgres 
hibernate.connection.password=1234 
hibernate.c3p0.min_size=5 
hibernate.c3p0.max_size=20 
hibernate.c3p0.timeout=1800 
hibernate.c3p0.max_statements=50
ou melhor ainda...
podemos obter as conexões de um DataSource 
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
destroy-method="close">! 
! <!-- access configuration -->! 
! <property name="driverClass" value="${jdbc.driverclass}" />! 
! <property name="jdbcUrl" value="${jdbc.url}" />! 
! <property name="user" value="${jdbc.username}" />! 
! <property name="password" value="${jdbc.password}" />! 
! <!-- pool sizing -->! 
! <property name="initialPoolSize" value="3" />! 
! <property name="minPoolSize" value="6" />! 
! <property name="maxPoolSize" value="25" />! 
! <property name="acquireIncrement" value="3" />! 
! <property name="maxStatements" value="0" />! 
! <!-- retries -->! 
! <property name="acquireRetryAttempts" value="30" />! 
! <property name="acquireRetryDelay" value="1000" /> <!-- 1s -->! 
! <property name="breakAfterAcquireFailure" value="false" />! 
! <!-- refreshing connections -->! 
! <property name="maxIdleTime" value="180" /> <!-- 3min -->! 
! <property name="maxConnectionAge" value="10" /> <!-- 1h -->! 
! <!-- timeouts e testing -->! 
! <property name="checkoutTimeout" value="5000" /> <!-- 5s -->! 
! <property name="idleConnectionTestPeriod" value="60" /> <!-- 60 -->! 
! <property name="testConnectionOnCheckout" value="true" />! 
! <property name="preferredTestQuery" value="SELECT 1+1" />! 
</bean>!
Pool traz melhoria de 
performance
Pool traz melhoria de 
performance 
mas não faz milagres
#2 
lidando com 
LazyInitialization 
Exception
quando e por que acontece?
@Entity 
class 
NotaFiscal 
{ 
… 
@OneToMany 
List<Item> 
itens; 
}
Percorrendo os itens de uma nota 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal.class, 
42); 
List<Item> 
itens 
= 
nf.getItens();
Hibernate executa 2 selects 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal.class, 
42); 
select nf.* from NotaFiscal nf 
where nf.id=42 
select i.* from Item i 
where i.nota_fiscal_id=42 
List<Item> 
itens 
= 
nf.getItens();
a session do Hibernate foi fechada 
Session 
session 
= 
sessionFactory.openSession(); 
! 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal.class, 
42); 
session.close(); 
! 
List<Item> 
itens 
= 
nf.getItens(); 
System.out.println("numero 
de 
pedidos:" 
+ 
itens.size());
mas ao ler os itens da nota 
Session 
session 
= 
sessionFactory.openSession(); 
! 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal. 
session.close(); 
! 
List<Item> 
itens 
= 
nf.getItens(); 
System.out.println( 
itens.size()); 
org.hibernate.LazyInitializationException: 
failed to lazily initialize a collection - 
no session or session was closed.
resolver parece fácil, certo?
fechar a session ao término do trabalho 
Session 
session 
= 
sessionFactory.openSession(); 
! 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal.class, 
42); 
! 
List<Item> 
itens 
= 
nf.getItens(); 
System.out.println("numero 
de 
pedidos:" 
+ 
itens.size()); 
session.close(); 
!
Mas e quando estamos 
trabalhando na Web?
NotaFiscalController.java 
@Get("/notas/{id}") 
public 
void 
view(Long 
id) 
{ 
NotaFiscal 
nf 
= 
notaFiscalDao.carrega(id); 
result.include("nf", 
nf); 
result.forwardTo("/notas/view.jsp"); 
} 
view.jsp 
<c:forEach 
var="item" 
items="${nf.itens}"> 
${item.produto.descricao}<br/> 
</c:forEach>
NotaFiscalController.java 
@Get("/notas/{id}") 
public 
void 
view(Long 
id) 
{ 
NotaFiscal 
nf 
= 
notaFiscalDao.carrega(id); 
result.include("nf", 
nf); 
result.forwardTo("/notas/view.jsp"); 
} 
view.jsp 
<c:forEach 
var="item" 
items="${nf.itens}"> 
${item.produto.descricao}<br/> 
</c:forEach> 
session foi fechada!
NotaFiscalController.java 
@Get("/notas/{id}") 
public 
void 
view(Long 
id) 
{ 
NotaFiscal 
nf 
= 
notaFiscalDao.carrega(id); 
result.include("nf", 
nf); 
result.forwardTo("/notas/view.jsp"); 
} 
view.jsp 
LazyInitializationException 
<c:forEach 
var="item" 
items="${nf.itens}"> 
${item.produto.descricao}<br/> 
</c:forEach>
e agora? #comofas
e agora? #comofas 
Sérgio 
passa tudo pra 
EAGER! ;D
@Entity 
class 
NotaFiscal 
{ 
… 
@OneToMany(fetch=FetchType.EAGER) 
List<Item> 
itens; 
}
Hibernate executa 1 select 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal.class, 
42); 
select nf.*, i.* from NotaFiscal 
nf left outer join Item i on 
nf.id = i.nota_fiscal_id 
where nf.id=42
mas isso poderia gerar 
uma sobrecarga...
mas isso poderia gerar 
uma sobrecarga... 
pois os itens da nota 
não são necessários em 
muitos lugares
lembre-se que ter os 
relacionamentos como LAZY é 
uma boa prática
como evitar LIE sem 
modificar o relacionamento 
para EAGER?
Open Session In 
View
@WebFilter(urlPatterns="/*") 
public 
class 
OpenSessionInViewFilter 
implements 
Filter 
{ 
! 
SessionFactory 
sessionFactory; 
@Override 
public 
void 
doFilter(ServletRequest 
req, 
ServletResponse 
res, 
FilterChain 
chain) 
{ 
Transaction 
transaction 
= 
null; 
try 
{ 
Session 
session 
= 
sessionFactory.getCurrentSession(); 
transaction 
= 
session.beginTransaction(); 
chain.doFilter(req, 
res); 
transaction.commit(); 
} 
finally 
{ 
if 
(transaction 
!= 
null 
&& 
transaction.isActive()) 
{ 
transaction.rollback(); 
} 
} 
} 
} 
Servlet Filter
o OSIV só evita LIE no 
mesmo request!
anti-pattern?
#3 
Second Level 
Cache
Carregando uma nota por ID 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal.class, 
42);
Session 
Banco de Dados
First Level Cache 
Session 
Banco de Dados
Session Session Session Session 
Banco de Dados
Session Session Session Session 
Second Level Cache 
Banco de Dados
First Level Cache 
Session Session Session 
Second Level Cache 
Banco de Dados 
Session
Session Session Session Session 
SessionFactory 
Banco de Dados
Configurar é simples
#1 configuramos o Hibernate 
hibernate.properties 
hibernate.cache.use_second_level_cache=true 
hibernate.cache.region.factory_class=net.sf.ehcac 
he.hibernate.EhCacheRegionFactory
@Entity 
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE) 
class 
Bug 
{ 
@Id 
private 
Long 
id; 
private 
String 
descricao; 
private 
String 
status; 
@ManyToOne 
private 
Projeto 
projeto; 
@OneToMany 
private 
List<Comentario> 
comentarios; 
} 
#2 configuramos as entidades
Caching Strategy 
@Cache( 
usage=CacheConcurrencyStrategy.READ_WRITE) 
READ_ONLY 
NONSTRICT_READ_WRITE 
READ_WRITE
Caching Strategy 
@Cache( 
usage=CacheConcurrencyStrategy.READ_WRITE) 
READ_ONLY 
NONSTRICT_READ_WRITE 
READ_WRITE 
Melhor performance
Caching Strategy 
@Cache( 
usage=CacheConcurrencyStrategy.READ_WRITE) 
READ_ONLY 
NONSTRICT_READ_WRITE 
READ_WRITE 
Dados não críticos
Caching Strategy 
@Cache( 
usage=CacheConcurrencyStrategy.READ_WRITE) 
READ_ONLY 
NONSTRICT_READ_WRITE 
READ_WRITE Modificações frequentes
ehcache.xml 
<cache 
name="br.com.triadworks.model.Bug" 
maxElementsInMemory="10000" 
eternal="false" 
timeToIdleSeconds="1800" 
timeToLiveSeconds="10000" 
overflowToDisk="true" 
memoryStoreEvictionPolicy="LRU" 
/>
Como 2nd Level Cache 
funciona?
2nd Level Cache não faz cache 
das instancias das entidades
2nd Level Cache não faz cache 
das instancias das entidades 
somente dos valores 
das propriedades
@Entity 
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE) 
class 
Bug 
{ 
@Id 
private 
Long 
id; 
private 
String 
descricao; 
private 
String 
status; 
@ManyToOne 
private 
Projeto 
projeto; 
@OneToMany 
private 
List<Comentario> 
comentarios; 
}
modelo conceitual do cache 
Bug Data Cache 
17 -> [ “Bug #1”, “ABERTA” , 1 ]! 
18 -> [ “Bug #2”, “FECHADA”, 2 ]! 
19 -> [ “Bug #3”, “ABERTA” , 1 ]
modelo conceitual do cache 
Bug Data Cache 
17 -> [ “Bug #1”, “ABERTA” , 1 ]! 
18 -> [ “Bug #2”, “FECHADA”, 2 ]! 
19 -> [ “Bug #3”, “ABERTA” , 1 ] 
id descricao status 
id do 
projeto
modelo conceitual do cache 
Bug Data Cache 
17 -> [ “Bug #1”, “ABERTA” , 1 ]! 
18 -> [ “Bug #2”, “FECHADA”, 2 ]! 
19 -> [ “Bug #3”, “ABERTA” , 1 ] 
não é uma árvore de objetos, 
mas sim um Map de Arrays
2nd Level Cache não faz cache 
das associações
@Entity 
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE) 
class 
Bug 
{ 
@Id 
private 
Long 
id; 
private 
String 
descricao; 
private 
String 
status; 
@ManyToOne 
private 
Projeto 
projeto; 
@OneToMany 
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE) 
private 
List<Comentario> 
comentarios; 
}
modelo conceitual do cache 
Bug Data Cache 
17 -> [ “Bug #1”, “ABERTA” , 1, [1,2] ]! 
18 -> [ “Bug #2”, “FECHADA”, 2, [] ]! 
19 -> [ “Bug #3”, “ABERTA” , 1, [3] ]
modelo conceitual do cache 
Bug Data Cache 
17 -> [ “Bug #1”, “ABERTA” , 1, [1,2] ]! 
18 -> [ “Bug #2”, “FECHADA”, 2, [] ]! 
19 -> [ “Bug #3”, “ABERTA” , 1, [3] ] 
ids dos 
comentarios
E o que o Hibernate faz com 
todos estes IDs?
E o que o Hibernate faz com 
todos estes IDs? 
vai no banco de 
novo! a não ser que 
você…
@Entity 
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE) 
class 
Projeto 
{ 
... 
} 
! 
! 
@Entity 
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY) 
class 
Comentario 
{ 
... 
} 
configure o cache das entidades
Devo cachear todas as 
minhas entidades?
Com 2nd Level Cache tudo funciona bem 
enquanto buscamos por ID... 
session.load(Bug.class, 
17);
Com 2nd Level Cache tudo funciona bem 
enquanto buscamos por ID... 
session.load(Bug.class, 
17); 
...mas e quando precisamos de uma 
consulta um pouco diferente? 
session 
.createQuery("from 
Bug 
where 
status 
= 
?") 
.setString(0,"ABERTO") 
.list();
#4 
Query Cache
Query Cache faz cache do 
resultado de uma query
Configurando Hibernate para 
usar Query Cache 
hibernate.properties 
hibernate.cache.use_query_cache=true
Query Cache 
session 
.createQuery("from 
Bug 
where 
status 
= 
?") 
.setString(0, 
status) 
.setCacheable(true) 
.list();
modelo conceitual do query cache 
Query Cache 
[“from Bug where status = ?”, [“ABERTO”]] -> [17, 19]
modelo conceitual do query cache 
Query Cache 
[“from Bug where status = ?”, [“ABERTO”]] -> [17, 19] 
Query + Parâmetros IDs
por isso Query Cache SEM 
2nd Level Cache não é de 
muita ajuda
Utilize somente em consultas 
que são executadas repetidas 
vezes com os mesmos 
parâmetros
Utilize somente em consultas 
que são executadas repetidas 
vezes com os mesmos 
parâmetros
#5 
Select n+1
o campeão em prejudicar 
a performance da 
aplicação
Processando os itens de uma nota 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal.class, 
42); 
processaItensDaNota(nf);
Hibernate executa 2 selects 
NotaFiscal 
nf 
= 
(NotaFiscal) 
session.load(NotaFiscal.class, 
42); 
select nf.* from NotaFiscal nf 
where nf.id=42 
select i.* from Item i 
where i.nota_fiscal_id=42 
processaItensDaNota(nf);
List<NotaFiscal> 
notas 
= 
dao.listaTudo(); 
for 
(NotaFiscal 
nf 
: 
notas) 
{ 
processaItensDaNota(nf); 
} 
Processando os itens de varias notas
Hibernate executa n+1 selects 
List<NotaFiscal> 
notas 
= 
dao.listaTudo(); 
select nf.* from NotaFiscal nf 
select i.* from Item i where i.nota_fiscal_id=? 
select i.* from Item i where i.nota_fiscal_id=? 
select i.* from Item i where i.nota_fiscal_id=? 
select i.* from Item i where i.nota_fiscal_id=? 
select i.* from Item i where i.nota_fiscal_id=? 
... 
for 
(NotaFiscal 
nf 
: 
notas) 
{ 
processaItensDaNota(nf); 
}
são muitos hits no banco de 
dados
são muitos hits no banco de 
dados 
mas podemos resolver 
isso...
3 soluções
#1 EAGER ou join-fetch
@Entity 
class 
NotaFiscal 
{ 
Utilizando FetchMode=EAGER 
… 
@OneToMany(fetch=FetchType.EAGER) 
List<Item> 
itens; 
}
Hibernate executa 1 select 
List<NotaFiscal> 
notas 
= 
dao.listaTudo(); 
select nf.*, i.* from NotaFiscal 
nf left outer join Item i on 
nf.id = i.nota_fiscal_id
antes de definir um 
mapeamento global deste 
tipo você precisa se 
perguntar...
SEMPRE que uma nota é 
necessária, todos seus 
itens também são 
necessários?
não?
Utilizando Join Fetch 
session 
.createQuery("from 
NotaFiscal 
n 
left 
join 
fetch 
n.itens") 
.list();
#2 batch-size nas 
associações
É o meio termo entre 
EAGER e LAZY
@Entity 
class 
NotaFiscal 
{ 
… 
@OneToMany 
@BatchSize(size=10) 
List<Item> 
itens; 
} 
@BatchSize
Hibernate executa n/10+1 selects 
List<NotaFiscal> 
notas 
= 
dao.listaTudo(); 
select nf.* from NotaFiscal nf 
select i.* from Item i where i.nota_fiscal_id 
in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 
select i.* from Item i where i.nota_fiscal_id 
in (?, ?, ?, ?, ?) 
for 
(NotaFiscal 
nf 
: 
notas) 
{ 
processaItensDaNota(nf); 
}
@BatchSize também é 
conhecido como:
@BatchSize também é 
conhecido como: 
otimização de adivinhação cega 
(blind-guess optimization)
@BatchSize também é 
conhecido como: 
otimização de adivinhação cega 
(blind-guess optimization) 
ou seja, é um palpite
#3 FetchMode 
SUBSELECT
@Entity 
class 
NotaFiscal 
{ 
… 
@OneToMany 
@Fetch(FetchMode.SUBSELECT) 
List<Item> 
itens; 
} 
SUBSELECT
Hibernate executa 2 selects 
List<NotaFiscal> 
notas 
= 
dao.listaTudo(); 
select nf.* from NotaFiscal nf 
select i.* from Item i where 
i.nota_fiscal_id in (select nf.id from 
NotaFiscal nf) 
for 
(NotaFiscal 
nf 
: 
notas) 
{ 
processaItensDaNota(nf); 
}
Qual utilizar?
Qual utilizar? 
depende
#6 
Processamento 
em lote
Imagine que temos que 
importar 100k produtos para 
o banco de dados
Session 
session 
= 
sf.openSession(); 
Transaction 
tx 
= 
session.beginTransaction(); 
for 
( 
int 
i=0; 
i 
< 
100000; 
i++ 
) 
{ 
Produto 
produto 
= 
new 
Produto(...); 
session.save(produto); 
} 
tx.commit(); 
session.close();
em ~50k produtos nós 
receberíamos um 
OutOfMemoryException
por que?
Hibernate faz cache de todas 
as instâncias dos Produtos 
inseridos na Session
mas como melhorar?
Session 
session 
= 
sf.openSession(); 
Transaction 
tx 
= 
session.beginTransaction(); 
for 
! 
! 
! 
( 
int 
i=0; 
i 
< 
100000; 
i++ 
) 
{ 
Produto 
produto 
= 
new 
Produto(...); 
session.save(produto); 
if 
(i 
% 
100 
== 
0) 
{ 
session.flush(); 
session.clear(); 
} 
} 
tx.commit(); 
session.close();
evitamos o OutOfMemoryException
evitamos o OutOfMemoryException 
Mas o processamento ainda 
continua lento!
evitamos o OutOfMemoryException 
Mas o processamento ainda 
continua lento! 
Dá pra melhorar?
JDBC puro?
JDBC puro? 
código de maxu! 
Handerson Frota
StatelessSession
API mais baixo nível 
sem 1st Level Cache 
próxima ao jdbc 
sem 2nd Level Cache 
mapeamento básico 
StatelessSession 
sem dirty-checking 
sem cascade 
Collections são ignorados 
sem modelo de 
eventos sem interceptors
StatelessSession 
session 
! 
= 
sf.openStatelessSession(); 
Transaction 
tx 
= 
session.beginTransaction(); 
for 
( 
int 
i=0; 
i 
< 
100000; 
i++ 
) 
{ 
Produto 
produto 
= 
new 
Produto(...); 
session.insert(produto); 
} 
tx.commit(); 
session.close();
menos consumo de memória 
e mais rápida!
menos consumo de memória 
e mais rápida! 
Yuri Adams 
dá pra melhorar?
hibernate.properties 
hibernate.jdbc.batch_size=50
CONCLUSÃO
Foi apenas a ponta o iceberg!
cada uma destas dicas são simples, 
mas requerem mais estudo
cada uma destas dicas são simples, 
mas requerem mais estudo 
pois depende do projeto
um DBA certamente pode te 
ajudar em muitos cenários
Hibernate não é seu inimigo, 
deixem de #mimimi
Rafael Ponte 
rponte@triadworks.com.br

More Related Content

What's hot

Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeZabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeIgor Nicoli
 
Desenvolvimento de jogos com HTML5 e javascript
Desenvolvimento de jogos com HTML5 e javascriptDesenvolvimento de jogos com HTML5 e javascript
Desenvolvimento de jogos com HTML5 e javascriptWillian Molinari
 
Boas práticas de Automação de Testes
Boas práticas de Automação de TestesBoas práticas de Automação de Testes
Boas práticas de Automação de TestesCamilo Ribeiro
 
Evento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontEvento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontMichel Ribeiro
 
MySQL 5.7 - 
Tirando o Máximo Proveito
MySQL 5.7 - 
Tirando o Máximo ProveitoMySQL 5.7 - 
Tirando o Máximo Proveito
MySQL 5.7 - 
Tirando o Máximo ProveitoGabriela Ferrara
 
Jurassic JavaScript Park - Rodando Offline até na ilha Nublar!
Jurassic JavaScript Park - Rodando Offline até na ilha Nublar!Jurassic JavaScript Park - Rodando Offline até na ilha Nublar!
Jurassic JavaScript Park - Rodando Offline até na ilha Nublar!Creditas
 
Dicas para Interfaces Performáticas no seu App Android
Dicas para Interfaces Performáticas no seu App AndroidDicas para Interfaces Performáticas no seu App Android
Dicas para Interfaces Performáticas no seu App AndroidUbiratan Soares
 
Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP Luis Gustavo Almeida
 
LaravelSP - MySQL 5.7: introdução ao JSON Data Type
LaravelSP - MySQL 5.7: introdução ao JSON Data TypeLaravelSP - MySQL 5.7: introdução ao JSON Data Type
LaravelSP - MySQL 5.7: introdução ao JSON Data TypeGabriela Ferrara
 
Evento Front End SP - Organizando o Javascript
 Evento Front End SP - Organizando o Javascript Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o JavascriptMichel Ribeiro
 
Prog web 03-php-sessoes-cookies_cabecalhos
Prog web 03-php-sessoes-cookies_cabecalhosProg web 03-php-sessoes-cookies_cabecalhos
Prog web 03-php-sessoes-cookies_cabecalhosRegis Magalhães
 
How to use Elasticsearch Analyzers by EmergiNet
How to use  Elasticsearch Analyzers by EmergiNetHow to use  Elasticsearch Analyzers by EmergiNet
How to use Elasticsearch Analyzers by EmergiNetEmergiNet
 
Prog web 03-php-sessoes-cookies_cabecalhos
Prog web 03-php-sessoes-cookies_cabecalhosProg web 03-php-sessoes-cookies_cabecalhos
Prog web 03-php-sessoes-cookies_cabecalhosRegis Magalhães
 
JS Experience 2017 - Javascript Funcional
JS Experience 2017 - Javascript FuncionalJS Experience 2017 - Javascript Funcional
JS Experience 2017 - Javascript FuncionaliMasters
 

What's hot (20)

Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividadeZabbix Conference LatAm 2019 - Automação: Ganhando produtividade
Zabbix Conference LatAm 2019 - Automação: Ganhando produtividade
 
Desenvolvimento de jogos com HTML5 e javascript
Desenvolvimento de jogos com HTML5 e javascriptDesenvolvimento de jogos com HTML5 e javascript
Desenvolvimento de jogos com HTML5 e javascript
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
Boas práticas de Automação de Testes
Boas práticas de Automação de TestesBoas práticas de Automação de Testes
Boas práticas de Automação de Testes
 
Evento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontEvento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de Front
 
MySQL 5.7 - 
Tirando o Máximo Proveito
MySQL 5.7 - 
Tirando o Máximo ProveitoMySQL 5.7 - 
Tirando o Máximo Proveito
MySQL 5.7 - 
Tirando o Máximo Proveito
 
Jurassic JavaScript Park - Rodando Offline até na ilha Nublar!
Jurassic JavaScript Park - Rodando Offline até na ilha Nublar!Jurassic JavaScript Park - Rodando Offline até na ilha Nublar!
Jurassic JavaScript Park - Rodando Offline até na ilha Nublar!
 
Dicas para Interfaces Performáticas no seu App Android
Dicas para Interfaces Performáticas no seu App AndroidDicas para Interfaces Performáticas no seu App Android
Dicas para Interfaces Performáticas no seu App Android
 
Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP Crawling - Coleta de dados na Web com PHP
Crawling - Coleta de dados na Web com PHP
 
Node.js: serious business
Node.js: serious businessNode.js: serious business
Node.js: serious business
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHPDoctrine2 Seminário PHP
Doctrine2 Seminário PHP
 
LaravelSP - MySQL 5.7: introdução ao JSON Data Type
LaravelSP - MySQL 5.7: introdução ao JSON Data TypeLaravelSP - MySQL 5.7: introdução ao JSON Data Type
LaravelSP - MySQL 5.7: introdução ao JSON Data Type
 
Java script aula 07 - j-query
Java script   aula 07 - j-queryJava script   aula 07 - j-query
Java script aula 07 - j-query
 
Evento Front End SP - Organizando o Javascript
 Evento Front End SP - Organizando o Javascript Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o Javascript
 
Prog web 03-php-sessoes-cookies_cabecalhos
Prog web 03-php-sessoes-cookies_cabecalhosProg web 03-php-sessoes-cookies_cabecalhos
Prog web 03-php-sessoes-cookies_cabecalhos
 
How to use Elasticsearch Analyzers by EmergiNet
How to use  Elasticsearch Analyzers by EmergiNetHow to use  Elasticsearch Analyzers by EmergiNet
How to use Elasticsearch Analyzers by EmergiNet
 
Prog web 03-php-sessoes-cookies_cabecalhos
Prog web 03-php-sessoes-cookies_cabecalhosProg web 03-php-sessoes-cookies_cabecalhos
Prog web 03-php-sessoes-cookies_cabecalhos
 
JS Experience 2017 - Javascript Funcional
JS Experience 2017 - Javascript FuncionalJS Experience 2017 - Javascript Funcional
JS Experience 2017 - Javascript Funcional
 
Tracking.js
Tracking.jsTracking.js
Tracking.js
 
Introdução ao MongoDB
Introdução ao MongoDBIntrodução ao MongoDB
Introdução ao MongoDB
 

Viewers also liked

Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)Rafael Ponte
 
Lidando com o Caos: Testando Código PLSQL em um Projeto Critico
Lidando com o Caos: Testando Código PLSQL em um Projeto CriticoLidando com o Caos: Testando Código PLSQL em um Projeto Critico
Lidando com o Caos: Testando Código PLSQL em um Projeto CriticoRafael Ponte
 
4 1-jpa-relacionamentos-many-to-one
4 1-jpa-relacionamentos-many-to-one4 1-jpa-relacionamentos-many-to-one
4 1-jpa-relacionamentos-many-to-oneLukinha92
 
Importancia dos Testes Automatizados no dia a dia (Don't Panic)
Importancia dos Testes Automatizados no dia a dia (Don't Panic)Importancia dos Testes Automatizados no dia a dia (Don't Panic)
Importancia dos Testes Automatizados no dia a dia (Don't Panic)Rafael Ponte
 
Importancia dos Testes Automatizados no dia a dia FIC-Estacio 2015
Importancia dos Testes Automatizados no dia a dia FIC-Estacio 2015Importancia dos Testes Automatizados no dia a dia FIC-Estacio 2015
Importancia dos Testes Automatizados no dia a dia FIC-Estacio 2015Rafael Ponte
 
Migrations for Java (QCONSP2013)
Migrations for Java (QCONSP2013)Migrations for Java (QCONSP2013)
Migrations for Java (QCONSP2013)Rafael Ponte
 
Hibernate Efetivo (QCONSP-2012)
Hibernate Efetivo (QCONSP-2012)Hibernate Efetivo (QCONSP-2012)
Hibernate Efetivo (QCONSP-2012)Rafael Ponte
 
Como Apresentar Codigo em Slides - Javou #7 - 2016
Como Apresentar Codigo em Slides - Javou #7 - 2016Como Apresentar Codigo em Slides - Javou #7 - 2016
Como Apresentar Codigo em Slides - Javou #7 - 2016Rafael Ponte
 

Viewers also liked (8)

Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
 
Lidando com o Caos: Testando Código PLSQL em um Projeto Critico
Lidando com o Caos: Testando Código PLSQL em um Projeto CriticoLidando com o Caos: Testando Código PLSQL em um Projeto Critico
Lidando com o Caos: Testando Código PLSQL em um Projeto Critico
 
4 1-jpa-relacionamentos-many-to-one
4 1-jpa-relacionamentos-many-to-one4 1-jpa-relacionamentos-many-to-one
4 1-jpa-relacionamentos-many-to-one
 
Importancia dos Testes Automatizados no dia a dia (Don't Panic)
Importancia dos Testes Automatizados no dia a dia (Don't Panic)Importancia dos Testes Automatizados no dia a dia (Don't Panic)
Importancia dos Testes Automatizados no dia a dia (Don't Panic)
 
Importancia dos Testes Automatizados no dia a dia FIC-Estacio 2015
Importancia dos Testes Automatizados no dia a dia FIC-Estacio 2015Importancia dos Testes Automatizados no dia a dia FIC-Estacio 2015
Importancia dos Testes Automatizados no dia a dia FIC-Estacio 2015
 
Migrations for Java (QCONSP2013)
Migrations for Java (QCONSP2013)Migrations for Java (QCONSP2013)
Migrations for Java (QCONSP2013)
 
Hibernate Efetivo (QCONSP-2012)
Hibernate Efetivo (QCONSP-2012)Hibernate Efetivo (QCONSP-2012)
Hibernate Efetivo (QCONSP-2012)
 
Como Apresentar Codigo em Slides - Javou #7 - 2016
Como Apresentar Codigo em Slides - Javou #7 - 2016Como Apresentar Codigo em Slides - Javou #7 - 2016
Como Apresentar Codigo em Slides - Javou #7 - 2016
 

Similar to Hibernate Efetivo: 6 dicas para melhorar performance

Mini curso hibernate com anotações
Mini curso hibernate com anotaçõesMini curso hibernate com anotações
Mini curso hibernate com anotaçõesdieguinhomcz
 
Mini curso hibernate com anotações
Mini curso hibernate com anotaçõesMini curso hibernate com anotações
Mini curso hibernate com anotaçõesdieguinhomcz
 
Persistência Java: Hibernate e JPA
Persistência Java: Hibernate e JPAPersistência Java: Hibernate e JPA
Persistência Java: Hibernate e JPACaelum
 
Boas práticas com jpa 2 e hibernate flisol 2012
Boas práticas com jpa 2 e hibernate   flisol 2012Boas práticas com jpa 2 e hibernate   flisol 2012
Boas práticas com jpa 2 e hibernate flisol 2012Frederico Maia Arantes
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmGuilherme Blanco
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1Sliedesharessbarbosa
 
TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?Rafael Benevides
 
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5Gilberto Holms
 
Os 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSFOs 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSFtarsobessa
 
Build Automation Evolved
Build Automation EvolvedBuild Automation Evolved
Build Automation EvolvedMarcelo Diniz
 
Migrations for Java (Javou #4 - JavaCE)
Migrations for Java (Javou #4 - JavaCE)Migrations for Java (Javou #4 - JavaCE)
Migrations for Java (Javou #4 - JavaCE)Rafael Ponte
 
Como ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noiteComo ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noiteComunidade NetPonto
 

Similar to Hibernate Efetivo: 6 dicas para melhorar performance (20)

Dev Ext PHP
Dev Ext PHPDev Ext PHP
Dev Ext PHP
 
Mini curso hibernate com anotações
Mini curso hibernate com anotaçõesMini curso hibernate com anotações
Mini curso hibernate com anotações
 
Mini curso hibernate com anotações
Mini curso hibernate com anotaçõesMini curso hibernate com anotações
Mini curso hibernate com anotações
 
Persistência Java: Hibernate e JPA
Persistência Java: Hibernate e JPAPersistência Java: Hibernate e JPA
Persistência Java: Hibernate e JPA
 
Conhecendo o Spring
Conhecendo o SpringConhecendo o Spring
Conhecendo o Spring
 
Boas práticas com jpa 2 e hibernate flisol 2012
Boas práticas com jpa 2 e hibernate   flisol 2012Boas práticas com jpa 2 e hibernate   flisol 2012
Boas práticas com jpa 2 e hibernate flisol 2012
 
Desenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine OrmDesenvolvimento Agil Com Doctrine Orm
Desenvolvimento Agil Com Doctrine Orm
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
 
TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?TDC 2014 SP - E o DeltaSpike ?
TDC 2014 SP - E o DeltaSpike ?
 
Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5Resumo Anotacoes Certificacao SCBCD 5
Resumo Anotacoes Certificacao SCBCD 5
 
Os 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSFOs 10 Maus Hábitos dos Desenvolvedores JSF
Os 10 Maus Hábitos dos Desenvolvedores JSF
 
Build Automation Evolved
Build Automation EvolvedBuild Automation Evolved
Build Automation Evolved
 
Hibernate conceitos
Hibernate conceitosHibernate conceitos
Hibernate conceitos
 
Realtime com node.js e socket.io
Realtime com node.js e socket.ioRealtime com node.js e socket.io
Realtime com node.js e socket.io
 
Academia ABAP
Academia  ABAPAcademia  ABAP
Academia ABAP
 
Cakephp 2.0 - O que mudou
Cakephp 2.0 - O que mudouCakephp 2.0 - O que mudou
Cakephp 2.0 - O que mudou
 
Migrations for Java (Javou #4 - JavaCE)
Migrations for Java (Javou #4 - JavaCE)Migrations for Java (Javou #4 - JavaCE)
Migrations for Java (Javou #4 - JavaCE)
 
Hibernate - Aula 01
Hibernate - Aula 01Hibernate - Aula 01
Hibernate - Aula 01
 
Como ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noiteComo ser programador durante o dia e mesmo assim dormir bem à noite
Como ser programador durante o dia e mesmo assim dormir bem à noite
 
Acessando o MySql com o Python
Acessando o MySql com o PythonAcessando o MySql com o Python
Acessando o MySql com o Python
 

More from Rafael Ponte

TechDay: 10 Features do Oracle que voce nao conhecia - CONNECT BY CLAUSE
TechDay: 10 Features do Oracle que voce nao conhecia - CONNECT BY CLAUSETechDay: 10 Features do Oracle que voce nao conhecia - CONNECT BY CLAUSE
TechDay: 10 Features do Oracle que voce nao conhecia - CONNECT BY CLAUSERafael Ponte
 
TechDay Retrospectiva 2018
TechDay Retrospectiva 2018TechDay Retrospectiva 2018
TechDay Retrospectiva 2018Rafael Ponte
 
Arquitetura Java - Escalando além do Hype
Arquitetura Java - Escalando além do HypeArquitetura Java - Escalando além do Hype
Arquitetura Java - Escalando além do HypeRafael Ponte
 
Como treinar seu estagiario
Como treinar seu estagiarioComo treinar seu estagiario
Como treinar seu estagiarioRafael Ponte
 
Importância dos testes automatizados no dia a dia
Importância dos testes automatizados no dia a diaImportância dos testes automatizados no dia a dia
Importância dos testes automatizados no dia a diaRafael Ponte
 
Migrations for Java
Migrations for JavaMigrations for Java
Migrations for JavaRafael Ponte
 
Importância dos testes automatizadoss
Importância dos testes automatizadossImportância dos testes automatizadoss
Importância dos testes automatizadossRafael Ponte
 
Greenbar - Testes automatizados na sua empresa
Greenbar - Testes automatizados na sua empresaGreenbar - Testes automatizados na sua empresa
Greenbar - Testes automatizados na sua empresaRafael Ponte
 
Desafios de um desenvolvedor JSF
Desafios de um desenvolvedor JSFDesafios de um desenvolvedor JSF
Desafios de um desenvolvedor JSFRafael Ponte
 
Curso de Java server faces (JSF)
Curso de Java server faces (JSF)Curso de Java server faces (JSF)
Curso de Java server faces (JSF)Rafael Ponte
 
Os 10 maus hábitos dos desenvolvedores JSF
Os 10 maus hábitos dos desenvolvedores JSFOs 10 maus hábitos dos desenvolvedores JSF
Os 10 maus hábitos dos desenvolvedores JSFRafael Ponte
 
Boas Práticas com JavaServer Faces (Jsf)
Boas Práticas com JavaServer Faces (Jsf)Boas Práticas com JavaServer Faces (Jsf)
Boas Práticas com JavaServer Faces (Jsf)Rafael Ponte
 
JavaServer Faces - Desenvolvendo aplicações web com produtividade
JavaServer Faces - Desenvolvendo aplicações web com produtividadeJavaServer Faces - Desenvolvendo aplicações web com produtividade
JavaServer Faces - Desenvolvendo aplicações web com produtividadeRafael Ponte
 
Entendendo Domain-Driven Design
Entendendo Domain-Driven DesignEntendendo Domain-Driven Design
Entendendo Domain-Driven DesignRafael Ponte
 
Anatomia do JSF, JavaServer Faces
Anatomia do JSF, JavaServer FacesAnatomia do JSF, JavaServer Faces
Anatomia do JSF, JavaServer FacesRafael Ponte
 

More from Rafael Ponte (15)

TechDay: 10 Features do Oracle que voce nao conhecia - CONNECT BY CLAUSE
TechDay: 10 Features do Oracle que voce nao conhecia - CONNECT BY CLAUSETechDay: 10 Features do Oracle que voce nao conhecia - CONNECT BY CLAUSE
TechDay: 10 Features do Oracle que voce nao conhecia - CONNECT BY CLAUSE
 
TechDay Retrospectiva 2018
TechDay Retrospectiva 2018TechDay Retrospectiva 2018
TechDay Retrospectiva 2018
 
Arquitetura Java - Escalando além do Hype
Arquitetura Java - Escalando além do HypeArquitetura Java - Escalando além do Hype
Arquitetura Java - Escalando além do Hype
 
Como treinar seu estagiario
Como treinar seu estagiarioComo treinar seu estagiario
Como treinar seu estagiario
 
Importância dos testes automatizados no dia a dia
Importância dos testes automatizados no dia a diaImportância dos testes automatizados no dia a dia
Importância dos testes automatizados no dia a dia
 
Migrations for Java
Migrations for JavaMigrations for Java
Migrations for Java
 
Importância dos testes automatizadoss
Importância dos testes automatizadossImportância dos testes automatizadoss
Importância dos testes automatizadoss
 
Greenbar - Testes automatizados na sua empresa
Greenbar - Testes automatizados na sua empresaGreenbar - Testes automatizados na sua empresa
Greenbar - Testes automatizados na sua empresa
 
Desafios de um desenvolvedor JSF
Desafios de um desenvolvedor JSFDesafios de um desenvolvedor JSF
Desafios de um desenvolvedor JSF
 
Curso de Java server faces (JSF)
Curso de Java server faces (JSF)Curso de Java server faces (JSF)
Curso de Java server faces (JSF)
 
Os 10 maus hábitos dos desenvolvedores JSF
Os 10 maus hábitos dos desenvolvedores JSFOs 10 maus hábitos dos desenvolvedores JSF
Os 10 maus hábitos dos desenvolvedores JSF
 
Boas Práticas com JavaServer Faces (Jsf)
Boas Práticas com JavaServer Faces (Jsf)Boas Práticas com JavaServer Faces (Jsf)
Boas Práticas com JavaServer Faces (Jsf)
 
JavaServer Faces - Desenvolvendo aplicações web com produtividade
JavaServer Faces - Desenvolvendo aplicações web com produtividadeJavaServer Faces - Desenvolvendo aplicações web com produtividade
JavaServer Faces - Desenvolvendo aplicações web com produtividade
 
Entendendo Domain-Driven Design
Entendendo Domain-Driven DesignEntendendo Domain-Driven Design
Entendendo Domain-Driven Design
 
Anatomia do JSF, JavaServer Faces
Anatomia do JSF, JavaServer FacesAnatomia do JSF, JavaServer Faces
Anatomia do JSF, JavaServer Faces
 

Hibernate Efetivo: 6 dicas para melhorar performance

  • 1. Hibernate EFETIVO ERROS COMUNS E SOLUÇÕES Rafael Ponte COALTI-2014 / ALJUG
  • 2. Eu estava me perguntando quando de fato o Hibernate foi criado...
  • 3. Eu estava me perguntando quando de fato o Hibernate foi criado... Luca Bastos O “Boom” foi em 2003!
  • 4. Mais de uma década! 2014 - 2003 = 11
  • 6. mas ainda hoje... existem devs que subutilizam o framework
  • 7. mas ainda hoje... existem devs que subutilizam o framework problemas de perfomance e escalabilidade
  • 10. culpam o Hibernate A culpa é do Banco de Dados! Sérgio
  • 11. é fácil culpar o que não se conhece...
  • 12. um SGDB mal configurado pode ser o problema...
  • 13. um SGDB mal configurado pode ser o problema... MAS na maioria das vezes o problema está na SUA APLICAÇÃO
  • 15. tabelas sem índices consultas mal-feitas <3 <3
  • 16. tabelas sem índices consultas mal-feitas <3 <3 <3 muitos hits ao banco
  • 17. tabelas sem índices consultas mal-feitas muitos hits ao banco connection leaks <3 <3 <3
  • 18. tabelas sem índices consultas mal-feitas muitos hits ao banco connection leaks <3 <3 <3 memory leaks
  • 19. Não saber tirar proveito framework
  • 20. Hibernate Efetivo 6 dicas para não deixar sua app morrer
  • 22.
  • 24.
  • 25.
  • 26.
  • 28. #1 POOL DE CONEXÕES
  • 29. com certeza todos aqui já ouviram falar...
  • 30. mas nem todos dão a devida atenção...
  • 31. mas nem todos dão a devida atenção... até perceberem a app engasgando
  • 32. mas nem todos dão a devida atenção... até perceberem a app engasgando ou até receberem um
  • 33. mas nem todos dão a devida atenção... até perceberem a app engasgando ou até receberem um org.hibernate.exception.Gener icJDBCException: Cannot open connection
  • 34. daí percebem que não configuraram o o pool do Hibernate hibernate.properties hibernate.connection.driver_class=org.postgresql.Driver hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect hibernate.connection.url=jdbc:postgresql://localhost:5432/myapp hibernate.connection.username=postgres hibernate.connection.password=1234 ! ! !
  • 35. daí percebem que não configuraram o o pool do Hibernate hibernate.properties hibernate.connection.driver_class=org.postgresql.Driver hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect hibernate.connection.url=jdbc:postgresql://localhost:5432/myapp hibernate.connection.username=postgres hibernate.connection.password=1234 hibernate.connection.pool_size=30 ! !
  • 36. daí percebem que não configuraram o o pool do Hibernate hibernate.properties hibernate.connection.driver_class=org.postgresql.Driver hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect hibernate.connection.url=jdbc:postgresql://localhost:5432/myapp hibernate.connection.username=postgres hibernate.connection.password=1234 hibernate.connection.pool_size=30 ! !
  • 37. a app volta a funcionar bem por um tempo
  • 38. a app volta a funcionar bem por um tempo
  • 39. e vão alocando mais conexões com o tempo hibernate.properties hibernate.connection.pool_size=30 40 55 70 ...
  • 40. o pool PADRÃO do Hibernate
  • 41. que possui uma impl. RUDIMENTAR
  • 42. INFO DriverManagerConnectionProvider:64 - Using Hibernate built-in connection pool (not for production use!)! INFO DriverManagerConnectionProvider:65 - Hibernate connection pool size: 20!
  • 43. not for production use! INFO DriverManagerConnectionProvider:64 - Using Hibernate built-in connection pool (not for production use!)! INFO DriverManagerConnectionProvider:65 - Hibernate connection pool size: 20!
  • 46. temos ótimas opções... pools como c3p0 ou commons-dbcp
  • 47. o Hibernate já vem com c3p0
  • 48. configurando c3p0 hibernate.properties hibernate.connection.driver_class=org.postgresql.Driver hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect hibernate.connection.url=jdbc:postgresql://localhost:5432/myapp hibernate.connection.username=postgres hibernate.connection.password=1234 hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.timeout=1800 hibernate.c3p0.max_statements=50
  • 50. podemos obter as conexões de um DataSource <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">! ! <!-- access configuration -->! ! <property name="driverClass" value="${jdbc.driverclass}" />! ! <property name="jdbcUrl" value="${jdbc.url}" />! ! <property name="user" value="${jdbc.username}" />! ! <property name="password" value="${jdbc.password}" />! ! <!-- pool sizing -->! ! <property name="initialPoolSize" value="3" />! ! <property name="minPoolSize" value="6" />! ! <property name="maxPoolSize" value="25" />! ! <property name="acquireIncrement" value="3" />! ! <property name="maxStatements" value="0" />! ! <!-- retries -->! ! <property name="acquireRetryAttempts" value="30" />! ! <property name="acquireRetryDelay" value="1000" /> <!-- 1s -->! ! <property name="breakAfterAcquireFailure" value="false" />! ! <!-- refreshing connections -->! ! <property name="maxIdleTime" value="180" /> <!-- 3min -->! ! <property name="maxConnectionAge" value="10" /> <!-- 1h -->! ! <!-- timeouts e testing -->! ! <property name="checkoutTimeout" value="5000" /> <!-- 5s -->! ! <property name="idleConnectionTestPeriod" value="60" /> <!-- 60 -->! ! <property name="testConnectionOnCheckout" value="true" />! ! <property name="preferredTestQuery" value="SELECT 1+1" />! </bean>!
  • 51. Pool traz melhoria de performance
  • 52. Pool traz melhoria de performance mas não faz milagres
  • 53. #2 lidando com LazyInitialization Exception
  • 54. quando e por que acontece?
  • 55. @Entity class NotaFiscal { … @OneToMany List<Item> itens; }
  • 56. Percorrendo os itens de uma nota NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42); List<Item> itens = nf.getItens();
  • 57. Hibernate executa 2 selects NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42); select nf.* from NotaFiscal nf where nf.id=42 select i.* from Item i where i.nota_fiscal_id=42 List<Item> itens = nf.getItens();
  • 58. a session do Hibernate foi fechada Session session = sessionFactory.openSession(); ! NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42); session.close(); ! List<Item> itens = nf.getItens(); System.out.println("numero de pedidos:" + itens.size());
  • 59. mas ao ler os itens da nota Session session = sessionFactory.openSession(); ! NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal. session.close(); ! List<Item> itens = nf.getItens(); System.out.println( itens.size()); org.hibernate.LazyInitializationException: failed to lazily initialize a collection - no session or session was closed.
  • 61. fechar a session ao término do trabalho Session session = sessionFactory.openSession(); ! NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42); ! List<Item> itens = nf.getItens(); System.out.println("numero de pedidos:" + itens.size()); session.close(); !
  • 62. Mas e quando estamos trabalhando na Web?
  • 63. NotaFiscalController.java @Get("/notas/{id}") public void view(Long id) { NotaFiscal nf = notaFiscalDao.carrega(id); result.include("nf", nf); result.forwardTo("/notas/view.jsp"); } view.jsp <c:forEach var="item" items="${nf.itens}"> ${item.produto.descricao}<br/> </c:forEach>
  • 64. NotaFiscalController.java @Get("/notas/{id}") public void view(Long id) { NotaFiscal nf = notaFiscalDao.carrega(id); result.include("nf", nf); result.forwardTo("/notas/view.jsp"); } view.jsp <c:forEach var="item" items="${nf.itens}"> ${item.produto.descricao}<br/> </c:forEach> session foi fechada!
  • 65. NotaFiscalController.java @Get("/notas/{id}") public void view(Long id) { NotaFiscal nf = notaFiscalDao.carrega(id); result.include("nf", nf); result.forwardTo("/notas/view.jsp"); } view.jsp LazyInitializationException <c:forEach var="item" items="${nf.itens}"> ${item.produto.descricao}<br/> </c:forEach>
  • 67. e agora? #comofas Sérgio passa tudo pra EAGER! ;D
  • 68. @Entity class NotaFiscal { … @OneToMany(fetch=FetchType.EAGER) List<Item> itens; }
  • 69. Hibernate executa 1 select NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42); select nf.*, i.* from NotaFiscal nf left outer join Item i on nf.id = i.nota_fiscal_id where nf.id=42
  • 70. mas isso poderia gerar uma sobrecarga...
  • 71. mas isso poderia gerar uma sobrecarga... pois os itens da nota não são necessários em muitos lugares
  • 72. lembre-se que ter os relacionamentos como LAZY é uma boa prática
  • 73. como evitar LIE sem modificar o relacionamento para EAGER?
  • 75. @WebFilter(urlPatterns="/*") public class OpenSessionInViewFilter implements Filter { ! SessionFactory sessionFactory; @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { Transaction transaction = null; try { Session session = sessionFactory.getCurrentSession(); transaction = session.beginTransaction(); chain.doFilter(req, res); transaction.commit(); } finally { if (transaction != null && transaction.isActive()) { transaction.rollback(); } } } } Servlet Filter
  • 76. o OSIV só evita LIE no mesmo request!
  • 79. Carregando uma nota por ID NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42);
  • 81. First Level Cache Session Banco de Dados
  • 82. Session Session Session Session Banco de Dados
  • 83. Session Session Session Session Second Level Cache Banco de Dados
  • 84. First Level Cache Session Session Session Second Level Cache Banco de Dados Session
  • 85. Session Session Session Session SessionFactory Banco de Dados
  • 87. #1 configuramos o Hibernate hibernate.properties hibernate.cache.use_second_level_cache=true hibernate.cache.region.factory_class=net.sf.ehcac he.hibernate.EhCacheRegionFactory
  • 88. @Entity @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) class Bug { @Id private Long id; private String descricao; private String status; @ManyToOne private Projeto projeto; @OneToMany private List<Comentario> comentarios; } #2 configuramos as entidades
  • 89. Caching Strategy @Cache( usage=CacheConcurrencyStrategy.READ_WRITE) READ_ONLY NONSTRICT_READ_WRITE READ_WRITE
  • 90. Caching Strategy @Cache( usage=CacheConcurrencyStrategy.READ_WRITE) READ_ONLY NONSTRICT_READ_WRITE READ_WRITE Melhor performance
  • 91. Caching Strategy @Cache( usage=CacheConcurrencyStrategy.READ_WRITE) READ_ONLY NONSTRICT_READ_WRITE READ_WRITE Dados não críticos
  • 92. Caching Strategy @Cache( usage=CacheConcurrencyStrategy.READ_WRITE) READ_ONLY NONSTRICT_READ_WRITE READ_WRITE Modificações frequentes
  • 93. ehcache.xml <cache name="br.com.triadworks.model.Bug" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="1800" timeToLiveSeconds="10000" overflowToDisk="true" memoryStoreEvictionPolicy="LRU" />
  • 94. Como 2nd Level Cache funciona?
  • 95. 2nd Level Cache não faz cache das instancias das entidades
  • 96. 2nd Level Cache não faz cache das instancias das entidades somente dos valores das propriedades
  • 97. @Entity @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) class Bug { @Id private Long id; private String descricao; private String status; @ManyToOne private Projeto projeto; @OneToMany private List<Comentario> comentarios; }
  • 98. modelo conceitual do cache Bug Data Cache 17 -> [ “Bug #1”, “ABERTA” , 1 ]! 18 -> [ “Bug #2”, “FECHADA”, 2 ]! 19 -> [ “Bug #3”, “ABERTA” , 1 ]
  • 99. modelo conceitual do cache Bug Data Cache 17 -> [ “Bug #1”, “ABERTA” , 1 ]! 18 -> [ “Bug #2”, “FECHADA”, 2 ]! 19 -> [ “Bug #3”, “ABERTA” , 1 ] id descricao status id do projeto
  • 100. modelo conceitual do cache Bug Data Cache 17 -> [ “Bug #1”, “ABERTA” , 1 ]! 18 -> [ “Bug #2”, “FECHADA”, 2 ]! 19 -> [ “Bug #3”, “ABERTA” , 1 ] não é uma árvore de objetos, mas sim um Map de Arrays
  • 101. 2nd Level Cache não faz cache das associações
  • 102. @Entity @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) class Bug { @Id private Long id; private String descricao; private String status; @ManyToOne private Projeto projeto; @OneToMany @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) private List<Comentario> comentarios; }
  • 103. modelo conceitual do cache Bug Data Cache 17 -> [ “Bug #1”, “ABERTA” , 1, [1,2] ]! 18 -> [ “Bug #2”, “FECHADA”, 2, [] ]! 19 -> [ “Bug #3”, “ABERTA” , 1, [3] ]
  • 104. modelo conceitual do cache Bug Data Cache 17 -> [ “Bug #1”, “ABERTA” , 1, [1,2] ]! 18 -> [ “Bug #2”, “FECHADA”, 2, [] ]! 19 -> [ “Bug #3”, “ABERTA” , 1, [3] ] ids dos comentarios
  • 105. E o que o Hibernate faz com todos estes IDs?
  • 106. E o que o Hibernate faz com todos estes IDs? vai no banco de novo! a não ser que você…
  • 107. @Entity @Cache(usage=CacheConcurrencyStrategy.READ_WRITE) class Projeto { ... } ! ! @Entity @Cache(usage=CacheConcurrencyStrategy.READ_ONLY) class Comentario { ... } configure o cache das entidades
  • 108. Devo cachear todas as minhas entidades?
  • 109. Com 2nd Level Cache tudo funciona bem enquanto buscamos por ID... session.load(Bug.class, 17);
  • 110. Com 2nd Level Cache tudo funciona bem enquanto buscamos por ID... session.load(Bug.class, 17); ...mas e quando precisamos de uma consulta um pouco diferente? session .createQuery("from Bug where status = ?") .setString(0,"ABERTO") .list();
  • 112. Query Cache faz cache do resultado de uma query
  • 113. Configurando Hibernate para usar Query Cache hibernate.properties hibernate.cache.use_query_cache=true
  • 114. Query Cache session .createQuery("from Bug where status = ?") .setString(0, status) .setCacheable(true) .list();
  • 115. modelo conceitual do query cache Query Cache [“from Bug where status = ?”, [“ABERTO”]] -> [17, 19]
  • 116. modelo conceitual do query cache Query Cache [“from Bug where status = ?”, [“ABERTO”]] -> [17, 19] Query + Parâmetros IDs
  • 117. por isso Query Cache SEM 2nd Level Cache não é de muita ajuda
  • 118. Utilize somente em consultas que são executadas repetidas vezes com os mesmos parâmetros
  • 119. Utilize somente em consultas que são executadas repetidas vezes com os mesmos parâmetros
  • 121. o campeão em prejudicar a performance da aplicação
  • 122. Processando os itens de uma nota NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42); processaItensDaNota(nf);
  • 123. Hibernate executa 2 selects NotaFiscal nf = (NotaFiscal) session.load(NotaFiscal.class, 42); select nf.* from NotaFiscal nf where nf.id=42 select i.* from Item i where i.nota_fiscal_id=42 processaItensDaNota(nf);
  • 124. List<NotaFiscal> notas = dao.listaTudo(); for (NotaFiscal nf : notas) { processaItensDaNota(nf); } Processando os itens de varias notas
  • 125. Hibernate executa n+1 selects List<NotaFiscal> notas = dao.listaTudo(); select nf.* from NotaFiscal nf select i.* from Item i where i.nota_fiscal_id=? select i.* from Item i where i.nota_fiscal_id=? select i.* from Item i where i.nota_fiscal_id=? select i.* from Item i where i.nota_fiscal_id=? select i.* from Item i where i.nota_fiscal_id=? ... for (NotaFiscal nf : notas) { processaItensDaNota(nf); }
  • 126. são muitos hits no banco de dados
  • 127. são muitos hits no banco de dados mas podemos resolver isso...
  • 129. #1 EAGER ou join-fetch
  • 130. @Entity class NotaFiscal { Utilizando FetchMode=EAGER … @OneToMany(fetch=FetchType.EAGER) List<Item> itens; }
  • 131. Hibernate executa 1 select List<NotaFiscal> notas = dao.listaTudo(); select nf.*, i.* from NotaFiscal nf left outer join Item i on nf.id = i.nota_fiscal_id
  • 132. antes de definir um mapeamento global deste tipo você precisa se perguntar...
  • 133. SEMPRE que uma nota é necessária, todos seus itens também são necessários?
  • 134. não?
  • 135. Utilizando Join Fetch session .createQuery("from NotaFiscal n left join fetch n.itens") .list();
  • 136. #2 batch-size nas associações
  • 137. É o meio termo entre EAGER e LAZY
  • 138. @Entity class NotaFiscal { … @OneToMany @BatchSize(size=10) List<Item> itens; } @BatchSize
  • 139. Hibernate executa n/10+1 selects List<NotaFiscal> notas = dao.listaTudo(); select nf.* from NotaFiscal nf select i.* from Item i where i.nota_fiscal_id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) select i.* from Item i where i.nota_fiscal_id in (?, ?, ?, ?, ?) for (NotaFiscal nf : notas) { processaItensDaNota(nf); }
  • 140. @BatchSize também é conhecido como:
  • 141. @BatchSize também é conhecido como: otimização de adivinhação cega (blind-guess optimization)
  • 142. @BatchSize também é conhecido como: otimização de adivinhação cega (blind-guess optimization) ou seja, é um palpite
  • 144. @Entity class NotaFiscal { … @OneToMany @Fetch(FetchMode.SUBSELECT) List<Item> itens; } SUBSELECT
  • 145. Hibernate executa 2 selects List<NotaFiscal> notas = dao.listaTudo(); select nf.* from NotaFiscal nf select i.* from Item i where i.nota_fiscal_id in (select nf.id from NotaFiscal nf) for (NotaFiscal nf : notas) { processaItensDaNota(nf); }
  • 149. Imagine que temos que importar 100k produtos para o banco de dados
  • 150. Session session = sf.openSession(); Transaction tx = session.beginTransaction(); for ( int i=0; i < 100000; i++ ) { Produto produto = new Produto(...); session.save(produto); } tx.commit(); session.close();
  • 151. em ~50k produtos nós receberíamos um OutOfMemoryException
  • 153. Hibernate faz cache de todas as instâncias dos Produtos inseridos na Session
  • 155. Session session = sf.openSession(); Transaction tx = session.beginTransaction(); for ! ! ! ( int i=0; i < 100000; i++ ) { Produto produto = new Produto(...); session.save(produto); if (i % 100 == 0) { session.flush(); session.clear(); } } tx.commit(); session.close();
  • 157. evitamos o OutOfMemoryException Mas o processamento ainda continua lento!
  • 158. evitamos o OutOfMemoryException Mas o processamento ainda continua lento! Dá pra melhorar?
  • 160. JDBC puro? código de maxu! Handerson Frota
  • 162. API mais baixo nível sem 1st Level Cache próxima ao jdbc sem 2nd Level Cache mapeamento básico StatelessSession sem dirty-checking sem cascade Collections são ignorados sem modelo de eventos sem interceptors
  • 163. StatelessSession session ! = sf.openStatelessSession(); Transaction tx = session.beginTransaction(); for ( int i=0; i < 100000; i++ ) { Produto produto = new Produto(...); session.insert(produto); } tx.commit(); session.close();
  • 164. menos consumo de memória e mais rápida!
  • 165. menos consumo de memória e mais rápida! Yuri Adams dá pra melhorar?
  • 168. Foi apenas a ponta o iceberg!
  • 169. cada uma destas dicas são simples, mas requerem mais estudo
  • 170. cada uma destas dicas são simples, mas requerem mais estudo pois depende do projeto
  • 171. um DBA certamente pode te ajudar em muitos cenários
  • 172. Hibernate não é seu inimigo, deixem de #mimimi