hibernate efetivo (qconsp-2012)

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

Upload: rafael-ponte

Post on 14-Jan-2015

14.081 views

Category:

Documents


0 download

DESCRIPTION

Mesmo anos após o lançamento do Hibernate ainda é fácil encontrar projetos utilizando o framework de maneira ineficiente, podendo leva-lo a problemas sérios de performance ou até inviabilizar a aplicação. O uso não efetivo do Hibernate está intimamente ligado a erros comuns e más práticas em sua utilização, que vão desde pool de conexões, select n+1, configuração de cache, batch-size até o uso indevido do cache level 1 em processamentos batch e o tratamento de LazyInitializationException.

TRANSCRIPT

Page 1: Hibernate Efetivo (QCONSP-2012)

Hibernate EFETIVOERROS COMUNS E SOLUÇÕES

Tuesday, August 7, 2012

Page 2: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 3: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

Quase uma década!2012 - 2003 = 9

Tuesday, August 7, 2012

Page 5: Hibernate Efetivo (QCONSP-2012)

mas ainda hoje...

Tuesday, August 7, 2012

Page 6: Hibernate Efetivo (QCONSP-2012)

mas ainda hoje...

existem devs que subutilizam o framework

Tuesday, August 7, 2012

Page 7: Hibernate Efetivo (QCONSP-2012)

mas ainda hoje...

existem devs que subutilizam o framework

problemas de perfomance e escalabilidade

Tuesday, August 7, 2012

Page 8: Hibernate Efetivo (QCONSP-2012)

e pra piorar...

Tuesday, August 7, 2012

Page 9: Hibernate Efetivo (QCONSP-2012)

culpam o Hibernate

Tuesday, August 7, 2012

Page 10: Hibernate Efetivo (QCONSP-2012)

culpam o Hibernate

A culpa é do Banco de Dados!

Sérgio

Tuesday, August 7, 2012

Page 11: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 12: Hibernate Efetivo (QCONSP-2012)

um SGDB mal configurado pode ser o problema...

Tuesday, August 7, 2012

Page 13: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

tabelas sem índices

<3Tuesday, August 7, 2012

Page 15: Hibernate Efetivo (QCONSP-2012)

tabelas sem índices

consultas mal-feitas

<3 <3Tuesday, August 7, 2012

Page 16: Hibernate Efetivo (QCONSP-2012)

tabelas sem índices

consultas mal-feitas

<3 <3 <3

muitos hits ao banco

Tuesday, August 7, 2012

Page 17: Hibernate Efetivo (QCONSP-2012)

tabelas sem índices

consultas mal-feitas

muitos hits ao banco

connection leaks

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

Page 18: Hibernate Efetivo (QCONSP-2012)

tabelas sem índices

consultas mal-feitas

muitos hits ao banco

connection leaks

<3 <3 <3

memory leaks

Tuesday, August 7, 2012

Page 19: Hibernate Efetivo (QCONSP-2012)

Não saber tirar proveito framework

Tuesday, August 7, 2012

Page 20: Hibernate Efetivo (QCONSP-2012)

Hibernate Efetivo6 dicas para não deixar

sua app morrer

Tuesday, August 7, 2012

Page 21: Hibernate Efetivo (QCONSP-2012)

@rponte

Tuesday, August 7, 2012

Page 22: Hibernate Efetivo (QCONSP-2012)

Tuesday, August 7, 2012

Page 23: Hibernate Efetivo (QCONSP-2012)

Fortaleza - Terra do SolTuesday, August 7, 2012

Page 24: Hibernate Efetivo (QCONSP-2012)

#1POOL DE

CONEXÕES

Tuesday, August 7, 2012

Page 25: Hibernate Efetivo (QCONSP-2012)

com certeza todos aqui já ouviram falar...

Tuesday, August 7, 2012

Page 26: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 27: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 28: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

a app volta a funcionar bem por um tempo

Tuesday, August 7, 2012

Page 34: Hibernate Efetivo (QCONSP-2012)

a app volta a funcionar bem por um tempo

Tuesday, August 7, 2012

Page 35: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

o pool PADRÃO do Hibernate

Tuesday, August 7, 2012

Page 37: Hibernate Efetivo (QCONSP-2012)

que possui uma impl. RUDIMENTAR

Tuesday, August 7, 2012

Page 38: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

qual pool utilizar?

Tuesday, August 7, 2012

Page 41: Hibernate Efetivo (QCONSP-2012)

temos ótimas opções...

Tuesday, August 7, 2012

Page 42: Hibernate Efetivo (QCONSP-2012)

pools como c3p0 ou commons-dbcp

temos ótimas opções...

Tuesday, August 7, 2012

Page 43: Hibernate Efetivo (QCONSP-2012)

o Hibernate já vem com c3p0

Tuesday, August 7, 2012

Page 44: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

ou melhor ainda...

Tuesday, August 7, 2012

Page 46: Hibernate Efetivo (QCONSP-2012)

<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 Efetivo (QCONSP-2012)

Pool traz melhoria de performance

Tuesday, August 7, 2012

Page 48: Hibernate Efetivo (QCONSP-2012)

Pool traz melhoria de performance

mas não faz milagres

Tuesday, August 7, 2012

Page 49: Hibernate Efetivo (QCONSP-2012)

#2lidando com

LazyInitializationException

Tuesday, August 7, 2012

Page 50: Hibernate Efetivo (QCONSP-2012)

quando e por que acontece?

Tuesday, August 7, 2012

Page 51: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 52: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

resolver parece fácil, certo?

Tuesday, August 7, 2012

Page 57: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

Mas e quando estamos trabalhando na Web?

Tuesday, August 7, 2012

Page 59: Hibernate Efetivo (QCONSP-2012)

@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 Efetivo (QCONSP-2012)

@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 Efetivo (QCONSP-2012)

e agora? #comofas

Tuesday, August 7, 2012

Page 62: Hibernate Efetivo (QCONSP-2012)

e agora? #comofas

Sérgio

passa tudo pra EAGER! ;D

Tuesday, August 7, 2012

Page 63: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 64: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

mas isso poderia gerar uma sobrecarga...

Tuesday, August 7, 2012

Page 66: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

lembre-se que ter os relacionamentos como LAZY é

uma boa prática

Tuesday, August 7, 2012

Page 68: Hibernate Efetivo (QCONSP-2012)

como evitar LIE sem modificar o relacionamento

para EAGER?

Tuesday, August 7, 2012

Page 69: Hibernate Efetivo (QCONSP-2012)

Open Session In View

Tuesday, August 7, 2012

Page 70: Hibernate Efetivo (QCONSP-2012)

@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 Efetivo (QCONSP-2012)

o OSIV só evita LIE no mesmo request!

Tuesday, August 7, 2012

Page 72: Hibernate Efetivo (QCONSP-2012)

anti-pattern?

Tuesday, August 7, 2012

Page 73: Hibernate Efetivo (QCONSP-2012)

#3Second Level

Cache

Tuesday, August 7, 2012

Page 74: Hibernate Efetivo (QCONSP-2012)

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

Carregando uma nota por ID

Tuesday, August 7, 2012

Page 75: Hibernate Efetivo (QCONSP-2012)

Banco de Dados

Session

Tuesday, August 7, 2012

Page 76: Hibernate Efetivo (QCONSP-2012)

Banco de Dados

Session

First Level Cache

Tuesday, August 7, 2012

Page 77: Hibernate Efetivo (QCONSP-2012)

Banco de Dados

Session Session Session Session

Tuesday, August 7, 2012

Page 78: Hibernate Efetivo (QCONSP-2012)

Banco de Dados

Second Level Cache

Session Session Session Session

Tuesday, August 7, 2012

Page 79: Hibernate Efetivo (QCONSP-2012)

Banco de Dados

Second Level Cache

Session Session Session Session

First Level Cache

Tuesday, August 7, 2012

Page 80: Hibernate Efetivo (QCONSP-2012)

Banco de Dados

SessionFactory

Session Session Session Session

Tuesday, August 7, 2012

Page 81: Hibernate Efetivo (QCONSP-2012)

Configurar é simples

Tuesday, August 7, 2012

Page 82: Hibernate Efetivo (QCONSP-2012)

#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 Efetivo (QCONSP-2012)

@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 Efetivo (QCONSP-2012)

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE

Tuesday, August 7, 2012

Page 85: Hibernate Efetivo (QCONSP-2012)

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE

Melhor performance

Tuesday, August 7, 2012

Page 86: Hibernate Efetivo (QCONSP-2012)

@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 Efetivo (QCONSP-2012)

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE Modificações frequentes

Tuesday, August 7, 2012

Page 88: Hibernate Efetivo (QCONSP-2012)

<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 Efetivo (QCONSP-2012)

Como 2nd Level Cache funciona?

Tuesday, August 7, 2012

Page 90: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 91: Hibernate Efetivo (QCONSP-2012)

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

somente dos valores das propriedades

Tuesday, August 7, 2012

Page 92: Hibernate Efetivo (QCONSP-2012)

@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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 96: Hibernate Efetivo (QCONSP-2012)

@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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

Devo cachear todas as minhas entidades?

Tuesday, August 7, 2012

Page 99: Hibernate Efetivo (QCONSP-2012)

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

session.load(Issue.class,  17);

Tuesday, August 7, 2012

Page 100: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

#4Query Cache

Tuesday, August 7, 2012

Page 102: Hibernate Efetivo (QCONSP-2012)

Query Cache faz cache do resultado de uma query

Tuesday, August 7, 2012

Page 103: Hibernate Efetivo (QCONSP-2012)

Configurando Hibernate para usar Query Cache

hibernate.cache.use_query_cache=true

hibernate.properties

Tuesday, August 7, 2012

Page 104: Hibernate Efetivo (QCONSP-2012)

Query Cache

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

Tuesday, August 7, 2012

Page 105: Hibernate Efetivo (QCONSP-2012)

modelo conceitual do query cache

Query Cache

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

Tuesday, August 7, 2012

Page 106: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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

muita ajuda

Tuesday, August 7, 2012

Page 108: Hibernate Efetivo (QCONSP-2012)

Utilize somente em consultas que são executadas repetidas

vezes com os mesmos parâmetros

Tuesday, August 7, 2012

Page 109: Hibernate Efetivo (QCONSP-2012)

Utilize somente em consultas que são executadas repetidas

vezes com os mesmos parâmetros

Tuesday, August 7, 2012

Page 110: Hibernate Efetivo (QCONSP-2012)

#5Select n+1

Tuesday, August 7, 2012

Page 111: Hibernate Efetivo (QCONSP-2012)

o campeão em prejudicar a performance da

aplicação

Tuesday, August 7, 2012

Page 112: Hibernate Efetivo (QCONSP-2012)

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

Processando os itens de uma nota

Tuesday, August 7, 2012

Page 113: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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

Processando os itens de varias notas

Tuesday, August 7, 2012

Page 115: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

são muitos hits no banco de dados

Tuesday, August 7, 2012

Page 117: Hibernate Efetivo (QCONSP-2012)

são muitos hits no banco de dados

mas podemos resolver isso...

Tuesday, August 7, 2012

Page 118: Hibernate Efetivo (QCONSP-2012)

3 soluções

Tuesday, August 7, 2012

Page 119: Hibernate Efetivo (QCONSP-2012)

#1 EAGER ou join-fetch

Tuesday, August 7, 2012

Page 120: Hibernate Efetivo (QCONSP-2012)

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

Utilizando FetchMode=EAGER

Tuesday, August 7, 2012

Page 121: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

antes de definir um mapeamento global deste

tipo você precisa se perguntar...

Tuesday, August 7, 2012

Page 123: Hibernate Efetivo (QCONSP-2012)

SEMPRE que uma nota é necessária, todos seus

itens também são necessários?

Tuesday, August 7, 2012

Page 124: Hibernate Efetivo (QCONSP-2012)

não?Tuesday, August 7, 2012

Page 125: Hibernate Efetivo (QCONSP-2012)

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

Utilizando Join Fetch

Tuesday, August 7, 2012

Page 126: Hibernate Efetivo (QCONSP-2012)

#2 batch-size nas associações

Tuesday, August 7, 2012

Page 127: Hibernate Efetivo (QCONSP-2012)

É o meio termo entre EAGER e LAZY

Tuesday, August 7, 2012

Page 128: Hibernate Efetivo (QCONSP-2012)

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

@BatchSize

Tuesday, August 7, 2012

Page 129: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

@BatchSize também é conhecido como:

Tuesday, August 7, 2012

Page 131: Hibernate Efetivo (QCONSP-2012)

@BatchSize também é conhecido como:

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

Tuesday, August 7, 2012

Page 132: Hibernate Efetivo (QCONSP-2012)

@BatchSize também é conhecido como:

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

ou seja, é um palpiteTuesday, August 7, 2012

Page 133: Hibernate Efetivo (QCONSP-2012)

#3 FetchMode SUBSELECT

Tuesday, August 7, 2012

Page 134: Hibernate Efetivo (QCONSP-2012)

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

SUBSELECT

Tuesday, August 7, 2012

Page 135: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

Qual utilizar?

Tuesday, August 7, 2012

Page 137: Hibernate Efetivo (QCONSP-2012)

Qual utilizar?

dependeTuesday, August 7, 2012

Page 138: Hibernate Efetivo (QCONSP-2012)

#6Processamento

em lote

Tuesday, August 7, 2012

Page 139: Hibernate Efetivo (QCONSP-2012)

Imagine que temos que importar 100k produtos para

o banco de dados

Tuesday, August 7, 2012

Page 140: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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

OutOfMemoryException

Tuesday, August 7, 2012

Page 142: Hibernate Efetivo (QCONSP-2012)

por que?

Tuesday, August 7, 2012

Page 143: Hibernate Efetivo (QCONSP-2012)

Hibernate faz cache de todas as instâncias dos Produtos

inseridos na Session

Tuesday, August 7, 2012

Page 144: Hibernate Efetivo (QCONSP-2012)

mas como melhorar?

Tuesday, August 7, 2012

Page 145: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

evitamos o OutOfMemoryException

Tuesday, August 7, 2012

Page 147: Hibernate Efetivo (QCONSP-2012)

evitamos o OutOfMemoryException

Mas o processamento ainda continua lento!

Tuesday, August 7, 2012

Page 148: Hibernate Efetivo (QCONSP-2012)

evitamos o OutOfMemoryException

Mas o processamento ainda continua lento!

Dá pra melhorar?

Tuesday, August 7, 2012

Page 149: Hibernate Efetivo (QCONSP-2012)

JDBC puro?

Tuesday, August 7, 2012

Page 150: Hibernate Efetivo (QCONSP-2012)

JDBC puro?

código de maxu!

Handerson Frota

Tuesday, August 7, 2012

Page 151: Hibernate Efetivo (QCONSP-2012)

StatelessSession

Tuesday, August 7, 2012

Page 152: Hibernate Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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 Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 155: Hibernate Efetivo (QCONSP-2012)

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

Yuri Adams

dá pra melhorar?

Tuesday, August 7, 2012

Page 156: Hibernate Efetivo (QCONSP-2012)

hibernate.jdbc.batch_size=50

hibernate.properties

Tuesday, August 7, 2012

Page 157: Hibernate Efetivo (QCONSP-2012)

CONCLUSÃO

Tuesday, August 7, 2012

Page 158: Hibernate Efetivo (QCONSP-2012)

Foi apenas a ponta o iceberg!

Tuesday, August 7, 2012

Page 159: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 160: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012

Page 161: Hibernate Efetivo (QCONSP-2012)

um DBA certamente pode ter ajudar em muitos cenários

Tuesday, August 7, 2012

Page 162: Hibernate Efetivo (QCONSP-2012)

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

Tuesday, August 7, 2012