hibernate - boas práticas e otimizações

163
Hibernate EFETIVO ERROS COMUNS E SOLUÇÕES Tuesday, August 7, 2012

Upload: leonardo-brancalhao

Post on 07-Dec-2014

1.896 views

Category:

Technology


0 download

DESCRIPTION

Pessoal, um excelente slide postado pelo Rafael Ponte, vale a pena conferir...

TRANSCRIPT

Page 1: Hibernate - Boas práticas e otimizações

Hibernate EFETIVOERROS COMUNS E SOLUÇÕES

Tuesday, August 7, 2012

Page 2: Hibernate - Boas práticas e otimizações

Eu estava me perguntando quando de fato o Hibernate foi criado...

Tuesday, August 7, 2012

Page 3: Hibernate - Boas práticas e otimizações

Eu estava me perguntando quando de fato o Hibernate foi criado...

Luca Bastos

O “Boom” foi em 2003!

Tuesday, August 7, 2012

Page 4: Hibernate - Boas práticas e otimizações

Quase uma década!2012 - 2003 = 9

Tuesday, August 7, 2012

Page 5: Hibernate - Boas práticas e otimizações

mas ainda hoje...

Tuesday, August 7, 2012

Page 6: Hibernate - Boas práticas e otimizações

mas ainda hoje...

existem devs que subutilizam o framework

Tuesday, August 7, 2012

Page 7: Hibernate - Boas práticas e otimizações

mas ainda hoje...

existem devs que subutilizam o framework

problemas de perfomance e escalabilidade

Tuesday, August 7, 2012

Page 8: Hibernate - Boas práticas e otimizações

e pra piorar...

Tuesday, August 7, 2012

Page 9: Hibernate - Boas práticas e otimizações

culpam o Hibernate

Tuesday, August 7, 2012

Page 10: Hibernate - Boas práticas e otimizações

culpam o Hibernate

A culpa é do Banco de Dados!

Sérgio

Tuesday, August 7, 2012

Page 11: Hibernate - Boas práticas e otimizações

é fácil culpar o que não se conhece...

Tuesday, August 7, 2012

Page 12: Hibernate - Boas práticas e otimizações

um SGDB mal configurado pode ser o problema...

Tuesday, August 7, 2012

Page 13: Hibernate - Boas práticas e otimizações

um SGDB mal configurado pode ser o problema...

MAS na maioria das vezes o

problema está na SUA APLICAÇÃO

Tuesday, August 7, 2012

Page 14: Hibernate - Boas práticas e otimizações

tabelas sem índices

<3Tuesday, August 7, 2012

Page 15: Hibernate - Boas práticas e otimizações

tabelas sem índices

consultas mal-feitas

<3 <3Tuesday, August 7, 2012

Page 16: Hibernate - Boas práticas e otimizações

tabelas sem índices

consultas mal-feitas

<3 <3 <3

muitos hits ao banco

Tuesday, August 7, 2012

Page 17: Hibernate - Boas práticas e otimizações

tabelas sem índices

consultas mal-feitas

muitos hits ao banco

connection leaks

<3 <3 <3Tuesday, August 7, 2012

Page 18: Hibernate - Boas práticas e otimizações

tabelas sem índices

consultas mal-feitas

muitos hits ao banco

connection leaks

<3 <3 <3

memory leaks

Tuesday, August 7, 2012

Page 19: Hibernate - Boas práticas e otimizações

Não saber tirar proveito framework

Tuesday, August 7, 2012

Page 20: Hibernate - Boas práticas e otimizações

Hibernate Efetivo6 dicas para não deixar

sua app morrer

Tuesday, August 7, 2012

Page 21: Hibernate - Boas práticas e otimizações

@rponte

Tuesday, August 7, 2012

Page 22: Hibernate - Boas práticas e otimizações

Tuesday, August 7, 2012

Page 23: Hibernate - Boas práticas e otimizações

Fortaleza - Terra do SolTuesday, August 7, 2012

Page 24: Hibernate - Boas práticas e otimizações

#1POOL DE

CONEXÕES

Tuesday, August 7, 2012

Page 25: Hibernate - Boas práticas e otimizações

com certeza todos aqui já ouviram falar...

Tuesday, August 7, 2012

Page 26: Hibernate - Boas práticas e otimizações

mas nem todos dão a devida atenção...

Tuesday, August 7, 2012

Page 27: Hibernate - Boas práticas e otimizações

mas nem todos dão a devida atenção...até perceberem a app engasgando

Tuesday, August 7, 2012

Page 28: Hibernate - Boas práticas e otimizações

mas nem todos dão a devida atenção...até perceberem a app engasgando

ou até receberem um

Tuesday, August 7, 2012

Page 29: Hibernate - Boas práticas e otimizações

mas nem todos dão a devida atenção...até perceberem a app engasgando

ou até receberem um

org.hibernate.exception.GenericJDBCException: Cannot

open connection

Tuesday, August 7, 2012

Page 30: Hibernate - Boas práticas e otimizações

daí percebem que não configuraram o o pool do Hibernate

hibernate.connection.driver_class=org.postgresql.Driverhibernate.dialect=org.hibernate.dialect.PostgreSQLDialecthibernate.connection.url=jdbc:postgresql://localhost:5432/myapphibernate.connection.username=postgreshibernate.connection.password=1234

hibernate.properties

Tuesday, August 7, 2012

Page 31: Hibernate - Boas práticas e otimizações

daí percebem que não configuraram o o pool do Hibernate

hibernate.connection.driver_class=org.postgresql.Driverhibernate.dialect=org.hibernate.dialect.PostgreSQLDialecthibernate.connection.url=jdbc:postgresql://localhost:5432/myapphibernate.connection.username=postgreshibernate.connection.password=1234hibernate.connection.pool_size=30

hibernate.properties

Tuesday, August 7, 2012

Page 32: Hibernate - Boas práticas e otimizações

daí percebem que não configuraram o o pool do Hibernate

hibernate.connection.driver_class=org.postgresql.Driverhibernate.dialect=org.hibernate.dialect.PostgreSQLDialecthibernate.connection.url=jdbc:postgresql://localhost:5432/myapphibernate.connection.username=postgreshibernate.connection.password=1234

hibernate.connection.pool_size=30

hibernate.properties

Tuesday, August 7, 2012

Page 33: Hibernate - Boas práticas e otimizações

a app volta a funcionar bem por um tempo

Tuesday, August 7, 2012

Page 34: Hibernate - Boas práticas e otimizações

a app volta a funcionar bem por um tempo

Tuesday, August 7, 2012

Page 35: Hibernate - Boas práticas e otimizações

e vão alocando mais conexões com o tempo

hibernate.connection.pool_size=30                                                              40                                                              55                                                              70                                                            ...

hibernate.properties

Tuesday, August 7, 2012

Page 36: Hibernate - Boas práticas e otimizações

o pool PADRÃO do Hibernate

Tuesday, August 7, 2012

Page 37: Hibernate - Boas práticas e otimizações

que possui uma impl. RUDIMENTAR

Tuesday, August 7, 2012

Page 38: Hibernate - Boas práticas e otimizações

INFO DriverManagerConnectionProvider:64 - Using Hibernate built-in connection pool (not for production use!)INFO DriverManagerConnectionProvider:65 - Hibernate connection pool size: 20

Tuesday, August 7, 2012

Page 39: Hibernate - Boas práticas e otimizações

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!

Tuesday, August 7, 2012

Page 40: Hibernate - Boas práticas e otimizações

qual pool utilizar?

Tuesday, August 7, 2012

Page 41: Hibernate - Boas práticas e otimizações

temos ótimas opções...

Tuesday, August 7, 2012

Page 42: Hibernate - Boas práticas e otimizações

pools como c3p0 ou commons-dbcp

temos ótimas opções...

Tuesday, August 7, 2012

Page 43: Hibernate - Boas práticas e otimizações

o Hibernate já vem com c3p0

Tuesday, August 7, 2012

Page 44: Hibernate - Boas práticas e otimizações

configurando c3p0

hibernate.connection.driver_class=org.postgresql.Driverhibernate.dialect=org.hibernate.dialect.PostgreSQLDialecthibernate.connection.url=jdbc:postgresql://localhost:5432/myapphibernate.connection.username=postgreshibernate.connection.password=1234hibernate.c3p0.min_size=5hibernate.c3p0.max_size=20hibernate.c3p0.timeout=1800hibernate.c3p0.max_statements=50

hibernate.properties

Tuesday, August 7, 2012

Page 45: Hibernate - Boas práticas e otimizações

ou melhor ainda...

Tuesday, August 7, 2012

Page 46: Hibernate - Boas práticas e otimizações

<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>

podemos obter as conexões de um DataSource

Tuesday, August 7, 2012

Page 47: Hibernate - Boas práticas e otimizações

Pool traz melhoria de performance

Tuesday, August 7, 2012

Page 48: Hibernate - Boas práticas e otimizações

Pool traz melhoria de performance

mas não faz milagres

Tuesday, August 7, 2012

Page 49: Hibernate - Boas práticas e otimizações

#2lidando com

LazyInitializationException

Tuesday, August 7, 2012

Page 50: Hibernate - Boas práticas e otimizações

quando e por que acontece?

Tuesday, August 7, 2012

Page 51: Hibernate - Boas práticas e otimizações

@Entityclass  NotaFiscal  {    …    @OneToMany    List<Item>  itens;}

Tuesday, August 7, 2012

Page 52: Hibernate - Boas práticas e otimizações

NotaFiscal  nf  =  (NotaFiscal)  session.load(NotaFiscal.class,  42);List<Item>  itens  =  nf.getItens();

Percorrendo os itens de uma nota

Tuesday, August 7, 2012

Page 53: Hibernate - Boas práticas e otimizações

select nf.* from NotaFiscal nf where nf.id=42

select i.* from Item i where i.nota_fiscal_id=42

Hibernate executa 2 selects

NotaFiscal  nf  =  (NotaFiscal)  session.load(NotaFiscal.class,  42);

List<Item>  itens  =  nf.getItens();

Tuesday, August 7, 2012

Page 54: Hibernate - Boas práticas e otimizações

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());

a session do Hibernate foi fechada

Tuesday, August 7, 2012

Page 55: Hibernate - Boas práticas e otimizações

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

org.hibernate.LazyInitializationException: failed to lazily initialize a collection -no session or session was closed.

Tuesday, August 7, 2012

Page 56: Hibernate - Boas práticas e otimizações

resolver parece fácil, certo?

Tuesday, August 7, 2012

Page 57: Hibernate - Boas práticas e otimizações

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();

fechar a session ao término do trabalho

Tuesday, August 7, 2012

Page 58: Hibernate - Boas práticas e otimizações

Mas e quando estamos trabalhando na Web?

Tuesday, August 7, 2012

Page 59: Hibernate - Boas práticas e otimizações

@Get("/notas/{id}")public  void  view(Long  id)  {    NotaFiscal  nf  =  notaFiscalDao.carrega(id);    result.include("nf",  nf);    result.forwardTo("/notas/view.jsp");}

view.jsp

NotaFiscalController.java

<c:forEach  var="item"  items="${nf.itens}">        ${item.produto.descricao}<br/></c:forEach>

Tuesday, August 7, 2012

Page 60: Hibernate - Boas práticas e otimizações

@Get("/notas/{id}")public  void  view(Long  id)  {    NotaFiscal  nf  =  notaFiscalDao.carrega(id);    result.include("nf",  nf);    result.forwardTo("/notas/view.jsp");}

view.jsp

NotaFiscalController.java

<c:forEach  var="item"  items="${nf.itens}">        ${item.produto.descricao}<br/></c:forEach>

LazyInitializationException

Tuesday, August 7, 2012

Page 61: Hibernate - Boas práticas e otimizações

e agora? #comofas

Tuesday, August 7, 2012

Page 62: Hibernate - Boas práticas e otimizações

e agora? #comofas

Sérgio

passa tudo pra EAGER! ;D

Tuesday, August 7, 2012

Page 63: Hibernate - Boas práticas e otimizações

@Entityclass  NotaFiscal  {    …    @OneToMany(fetch=FetchType.EAGER)    List<Item>  itens;}

Tuesday, August 7, 2012

Page 64: Hibernate - Boas práticas e otimizações

select nf.*, i.* from NotaFiscal nf left outer join Item i on nf.id = i.nota_fiscal_idwhere nf.id=42

Hibernate executa 1 select

NotaFiscal  nf  =  (NotaFiscal)  session.load(NotaFiscal.class,  42);

Tuesday, August 7, 2012

Page 65: Hibernate - Boas práticas e otimizações

mas isso poderia gerar uma sobrecarga...

Tuesday, August 7, 2012

Page 66: Hibernate - Boas práticas e otimizações

mas isso poderia gerar uma sobrecarga...

pois os itens da nota não são necessários em

muitos lugares Tuesday, August 7, 2012

Page 67: Hibernate - Boas práticas e otimizações

lembre-se que ter os relacionamentos como LAZY é

uma boa prática

Tuesday, August 7, 2012

Page 68: Hibernate - Boas práticas e otimizações

como evitar LIE sem modificar o relacionamento

para EAGER?

Tuesday, August 7, 2012

Page 69: Hibernate - Boas práticas e otimizações

Open Session In View

Tuesday, August 7, 2012

Page 70: Hibernate - Boas práticas e otimizações

@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

Tuesday, August 7, 2012

Page 71: Hibernate - Boas práticas e otimizações

o OSIV só evita LIE no mesmo request!

Tuesday, August 7, 2012

Page 72: Hibernate - Boas práticas e otimizações

anti-pattern?

Tuesday, August 7, 2012

Page 73: Hibernate - Boas práticas e otimizações

#3Second Level

Cache

Tuesday, August 7, 2012

Page 74: Hibernate - Boas práticas e otimizações

NotaFiscal  nf  =  (NotaFiscal)  session.load(NotaFiscal.class,  42);

Carregando uma nota por ID

Tuesday, August 7, 2012

Page 75: Hibernate - Boas práticas e otimizações

Banco de Dados

Session

Tuesday, August 7, 2012

Page 76: Hibernate - Boas práticas e otimizações

Banco de Dados

Session

First Level Cache

Tuesday, August 7, 2012

Page 77: Hibernate - Boas práticas e otimizações

Banco de Dados

Session Session Session Session

Tuesday, August 7, 2012

Page 78: Hibernate - Boas práticas e otimizações

Banco de Dados

Second Level Cache

Session Session Session Session

Tuesday, August 7, 2012

Page 79: Hibernate - Boas práticas e otimizações

Banco de Dados

Second Level Cache

Session Session Session Session

First Level Cache

Tuesday, August 7, 2012

Page 80: Hibernate - Boas práticas e otimizações

Banco de Dados

SessionFactory

Session Session Session Session

Tuesday, August 7, 2012

Page 81: Hibernate - Boas práticas e otimizações

Configurar é simples

Tuesday, August 7, 2012

Page 82: Hibernate - Boas práticas e otimizações

#1 configuramos o Hibernate

hibernate.cache.use_second_level_cache=truehibernate.cache.region.factory_class=net.sf.ehcache.hibernate.EhCacheRegionFactory

hibernate.properties

Tuesday, August 7, 2012

Page 83: Hibernate - Boas práticas e otimizações

@Entity@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)class  Issue  {@Id

   private  Long  id;private  String  descricao;private  String  status;@ManyToOneprivate  Projeto  projeto;

   @OneToMany    private  List<Comentario>  comentarios;}

#2 configuramos as entidades

Tuesday, August 7, 2012

Page 84: Hibernate - Boas práticas e otimizações

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE

Tuesday, August 7, 2012

Page 85: Hibernate - Boas práticas e otimizações

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE

Melhor performance

Tuesday, August 7, 2012

Page 86: Hibernate - Boas práticas e otimizações

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE

Dados não críticos

Tuesday, August 7, 2012

Page 87: Hibernate - Boas práticas e otimizações

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE Modificações frequentes

Tuesday, August 7, 2012

Page 88: Hibernate - Boas práticas e otimizações

<cache        name="br.com.triadworks.model.Issue"        maxElementsInMemory="10000"        eternal="false"        timeToIdleSeconds="1800"        timeToLiveSeconds="10000"        overflowToDisk="true"        memoryStoreEvictionPolicy="LRU"/>

ehcache.xml

Tuesday, August 7, 2012

Page 89: Hibernate - Boas práticas e otimizações

Como 2nd Level Cache funciona?

Tuesday, August 7, 2012

Page 90: Hibernate - Boas práticas e otimizações

2nd Level Cache não faz cache das instancias das entidades

Tuesday, August 7, 2012

Page 91: Hibernate - Boas práticas e otimizações

2nd Level Cache não faz cache das instancias das entidades

somente dos valores das propriedades

Tuesday, August 7, 2012

Page 92: Hibernate - Boas práticas e otimizações

@Entity@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)class  Issue  {@Id

   private  Long  id;private  String  descricao;private  String  status;@ManyToOneprivate  Projeto  projeto;

   @OneToMany    private  List<Comentario>  comentarios;}

Tuesday, August 7, 2012

Page 93: Hibernate - Boas práticas e otimizações

modelo conceitual do cache

Issue Data Cache

17 -> [ “Bug #1”, “ABERTA” , 1 ]18 -> [ “Bug #2”, “FECHADA”, 2 ]19 -> [ “Bug #3”, “ABERTA” , 1 ]

Tuesday, August 7, 2012

Page 94: Hibernate - Boas práticas e otimizações

modelo conceitual do cache

Issue 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"

Tuesday, August 7, 2012

Page 95: Hibernate - Boas práticas e otimizações

2nd Level Cache não faz cache das associações

Tuesday, August 7, 2012

Page 96: Hibernate - Boas práticas e otimizações

@Entity@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)class  Issue  {@Id

   private  Long  id;private  String  descricao;private  String  status;@ManyToOneprivate  Projeto  projeto;

   @OneToMany    @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)    private  List<Comentario>  comentarios;}

Tuesday, August 7, 2012

Page 97: Hibernate - Boas práticas e otimizações

modelo conceitual do cache

Issue Data Cache

17 -> [ “Bug #1”, “ABERTA” , 1, [1,2] ]18 -> [ “Bug #2”, “FECHADA”, 2, [] ]19 -> [ “Bug #3”, “ABERTA” , 1, [3] ]

Tuesday, August 7, 2012

Page 98: Hibernate - Boas práticas e otimizações

Devo cachear todas as minhas entidades?

Tuesday, August 7, 2012

Page 99: Hibernate - Boas práticas e otimizações

Com 2nd Level Cache tudo funciona bem enquanto buscamos por ID...

session.load(Issue.class,  17);

Tuesday, August 7, 2012

Page 100: Hibernate - Boas práticas e otimizações

Com 2nd Level Cache tudo funciona bem enquanto buscamos por ID...

...mas e quando precisamos de uma consulta um pouco diferente?

session.load(Issue.class,  17);

session    .createQuery("from  Issue  where  status  =  ?")    .setString(0,"ABERTO")    .list();  

Tuesday, August 7, 2012

Page 101: Hibernate - Boas práticas e otimizações

#4Query Cache

Tuesday, August 7, 2012

Page 102: Hibernate - Boas práticas e otimizações

Query Cache faz cache do resultado de uma query

Tuesday, August 7, 2012

Page 103: Hibernate - Boas práticas e otimizações

Configurando Hibernate para usar Query Cache

hibernate.cache.use_query_cache=true

hibernate.properties

Tuesday, August 7, 2012

Page 104: Hibernate - Boas práticas e otimizações

Query Cache

session    .createQuery("from  Issue  where  status  =  ?")    .setString(0,  status)    .setCacheable(true)    .list();  

Tuesday, August 7, 2012

Page 105: Hibernate - Boas práticas e otimizações

modelo conceitual do query cache

Query Cache

[“from Issue where status = ?”, [“ABERTA”]] -> [17, 19]

Tuesday, August 7, 2012

Page 106: Hibernate - Boas práticas e otimizações

modelo conceitual do query cache

Query Cache

[“from Issue where status = ?”, [“ABERTA”]] -> [17, 19]

Query + Parâmetros IDs

Tuesday, August 7, 2012

Page 107: Hibernate - Boas práticas e otimizações

por isso Query Cache SEM 2nd Level Cache não é de

muita ajuda

Tuesday, August 7, 2012

Page 108: Hibernate - Boas práticas e otimizações

Utilize somente em consultas que são executadas repetidas

vezes com os mesmos parâmetros

Tuesday, August 7, 2012

Page 109: Hibernate - Boas práticas e otimizações

Utilize somente em consultas que são executadas repetidas

vezes com os mesmos parâmetros

Tuesday, August 7, 2012

Page 110: Hibernate - Boas práticas e otimizações

#5Select n+1

Tuesday, August 7, 2012

Page 111: Hibernate - Boas práticas e otimizações

o campeão em prejudicar a performance da

aplicação

Tuesday, August 7, 2012

Page 112: Hibernate - Boas práticas e otimizações

NotaFiscal  nf  =  (NotaFiscal)  session.load(NotaFiscal.class,  42);processaItensDaNota(nf);

Processando os itens de uma nota

Tuesday, August 7, 2012

Page 113: Hibernate - Boas práticas e otimizações

select nf.* from NotaFiscal nf where nf.id=42

select i.* from Item i where i.nota_fiscal_id=42

Hibernate executa 2 selects

NotaFiscal  nf  =  (NotaFiscal)  session.load(NotaFiscal.class,  42);

processaItensDaNota(nf);

Tuesday, August 7, 2012

Page 114: Hibernate - Boas práticas e otimizações

List<NotaFiscal>  notas  =  dao.listaTudo();for  (NotaFiscal  nf  :  notas)  {        processaItensDaNota(nf);}

Processando os itens de varias notas

Tuesday, August 7, 2012

Page 115: Hibernate - Boas práticas e otimizações

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=? ...

Hibernate executa n+1 selects

List<NotaFiscal>  notas  =  dao.listaTudo();

for  (NotaFiscal  nf  :  notas)  {        processaItensDaNota(nf);}

Tuesday, August 7, 2012

Page 116: Hibernate - Boas práticas e otimizações

são muitos hits no banco de dados

Tuesday, August 7, 2012

Page 117: Hibernate - Boas práticas e otimizações

são muitos hits no banco de dados

mas podemos resolver isso...

Tuesday, August 7, 2012

Page 118: Hibernate - Boas práticas e otimizações

3 soluções

Tuesday, August 7, 2012

Page 119: Hibernate - Boas práticas e otimizações

#1 EAGER ou join-fetch

Tuesday, August 7, 2012

Page 120: Hibernate - Boas práticas e otimizações

@Entityclass  NotaFiscal  {    …    @OneToMany(fetch=FetchType.EAGER)    List<Item>  itens;}

Utilizando FetchMode=EAGER

Tuesday, August 7, 2012

Page 121: Hibernate - Boas práticas e otimizações

select nf.*, i.* from NotaFiscal nf left outer join Item i on nf.id = i.nota_fiscal_id

Hibernate executa 1 select

List<NotaFiscal>  notas  =  dao.listaTudo();

Tuesday, August 7, 2012

Page 122: Hibernate - Boas práticas e otimizações

antes de definir um mapeamento global deste

tipo você precisa se perguntar...

Tuesday, August 7, 2012

Page 123: Hibernate - Boas práticas e otimizações

SEMPRE que uma nota é necessária, todos seus

itens também são necessários?

Tuesday, August 7, 2012

Page 124: Hibernate - Boas práticas e otimizações

não?Tuesday, August 7, 2012

Page 125: Hibernate - Boas práticas e otimizações

session    .createQuery("from  NotaFiscal  n  left  join  fetch  n.itens")    .list();  

Utilizando Join Fetch

Tuesday, August 7, 2012

Page 126: Hibernate - Boas práticas e otimizações

#2 batch-size nas associações

Tuesday, August 7, 2012

Page 127: Hibernate - Boas práticas e otimizações

É o meio termo entre EAGER e LAZY

Tuesday, August 7, 2012

Page 128: Hibernate - Boas práticas e otimizações

@Entityclass  NotaFiscal  {    …    @OneToMany    @BatchSize(size=10)    List<Item>  itens;}

@BatchSize

Tuesday, August 7, 2012

Page 129: Hibernate - Boas práticas e otimizações

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 (?, ?, ?, ?, ?)

Hibernate executa n/10+1 selects

List<NotaFiscal>  notas  =  dao.listaTudo();

for  (NotaFiscal  nf  :  notas)  {        processaItensDaNota(nf);}

Tuesday, August 7, 2012

Page 130: Hibernate - Boas práticas e otimizações

@BatchSize também é conhecido como:

Tuesday, August 7, 2012

Page 131: Hibernate - Boas práticas e otimizações

@BatchSize também é conhecido como:

otimização de adivinhação cega(blind-guess optimization)

Tuesday, August 7, 2012

Page 132: Hibernate - Boas práticas e otimizações

@BatchSize também é conhecido como:

otimização de adivinhação cega(blind-guess optimization)

ou seja, é um palpiteTuesday, August 7, 2012

Page 133: Hibernate - Boas práticas e otimizações

#3 FetchMode SUBSELECT

Tuesday, August 7, 2012

Page 134: Hibernate - Boas práticas e otimizações

@Entityclass  NotaFiscal  {    …    @OneToMany    @Fetch(FetchMode.SUBSELECT)    List<Item>  itens;}

SUBSELECT

Tuesday, August 7, 2012

Page 135: Hibernate - Boas práticas e otimizações

select nf.* from NotaFiscal nf

select i.* from Item i where i.nota_fiscal_id in (select nf.id from NotaFiscal nf)

Hibernate executa 2 selects

List<NotaFiscal>  notas  =  dao.listaTudo();

for  (NotaFiscal  nf  :  notas)  {        processaItensDaNota(nf);}

Tuesday, August 7, 2012

Page 136: Hibernate - Boas práticas e otimizações

Qual utilizar?

Tuesday, August 7, 2012

Page 137: Hibernate - Boas práticas e otimizações

Qual utilizar?

dependeTuesday, August 7, 2012

Page 138: Hibernate - Boas práticas e otimizações

#6Processamento

em lote

Tuesday, August 7, 2012

Page 139: Hibernate - Boas práticas e otimizações

Imagine que temos que importar 100k produtos para

o banco de dados

Tuesday, August 7, 2012

Page 140: Hibernate - Boas práticas e otimizações

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();

Tuesday, August 7, 2012

Page 141: Hibernate - Boas práticas e otimizações

em ~50k produtos nós receberíamos um

OutOfMemoryException

Tuesday, August 7, 2012

Page 142: Hibernate - Boas práticas e otimizações

por que?

Tuesday, August 7, 2012

Page 143: Hibernate - Boas práticas e otimizações

Hibernate faz cache de todas as instâncias dos Produtos

inseridos na Session

Tuesday, August 7, 2012

Page 144: Hibernate - Boas práticas e otimizações

mas como melhorar?

Tuesday, August 7, 2012

Page 145: Hibernate - Boas práticas e otimizações

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();

Tuesday, August 7, 2012

Page 146: Hibernate - Boas práticas e otimizações

evitamos o OutOfMemoryException

Tuesday, August 7, 2012

Page 147: Hibernate - Boas práticas e otimizações

evitamos o OutOfMemoryException

Mas o processamento ainda continua lento!

Tuesday, August 7, 2012

Page 148: Hibernate - Boas práticas e otimizações

evitamos o OutOfMemoryException

Mas o processamento ainda continua lento!

Dá pra melhorar?

Tuesday, August 7, 2012

Page 149: Hibernate - Boas práticas e otimizações

JDBC puro?

Tuesday, August 7, 2012

Page 150: Hibernate - Boas práticas e otimizações

JDBC puro?

código de maxu!

Handerson Frota

Tuesday, August 7, 2012

Page 151: Hibernate - Boas práticas e otimizações

StatelessSession

Tuesday, August 7, 2012

Page 152: Hibernate - Boas práticas e otimizações

StatelessSession

sem 1st Level Cache

sem 2nd Level Cache

sem dirty-checking

sem cascade

Collections são ignorados

sem modelo de eventos sem interceptors

próxima ao jdbc

API mais baixo nível

mapeamento básico

Tuesday, August 7, 2012

Page 153: Hibernate - Boas práticas e otimizações

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();

Tuesday, August 7, 2012

Page 154: Hibernate - Boas práticas e otimizações

menos consumo de memória e mais rápida!

Tuesday, August 7, 2012

Page 155: Hibernate - Boas práticas e otimizações

menos consumo de memória e mais rápida!

Yuri Adams

dá pra melhorar?

Tuesday, August 7, 2012

Page 156: Hibernate - Boas práticas e otimizações

hibernate.jdbc.batch_size=50

hibernate.properties

Tuesday, August 7, 2012

Page 157: Hibernate - Boas práticas e otimizações

CONCLUSÃO

Tuesday, August 7, 2012

Page 158: Hibernate - Boas práticas e otimizações

Foi apenas a ponta o iceberg!

Tuesday, August 7, 2012

Page 159: Hibernate - Boas práticas e otimizações

cada uma destas dicas são simples, mas requerem mais estudo

Tuesday, August 7, 2012

Page 160: Hibernate - Boas práticas e otimizações

cada uma destas dicas são simples, mas requerem mais estudopois depende do projeto

Tuesday, August 7, 2012

Page 161: Hibernate - Boas práticas e otimizações

um DBA certamente pode ter ajudar em muitos cenários

Tuesday, August 7, 2012

Page 162: Hibernate - Boas práticas e otimizações

Hibernate não é seu inimigo, deixem de #mimimi

Tuesday, August 7, 2012