hibernate efetivo (qconsp-2012)

Post on 14-Jan-2015

14.080 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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

Hibernate EFETIVOERROS COMUNS E SOLUÇÕES

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

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

Luca Bastos

O “Boom” foi em 2003!

Tuesday, August 7, 2012

Quase uma década!2012 - 2003 = 9

Tuesday, August 7, 2012

mas ainda hoje...

Tuesday, August 7, 2012

mas ainda hoje...

existem devs que subutilizam o framework

Tuesday, August 7, 2012

mas ainda hoje...

existem devs que subutilizam o framework

problemas de perfomance e escalabilidade

Tuesday, August 7, 2012

e pra piorar...

Tuesday, August 7, 2012

culpam o Hibernate

Tuesday, August 7, 2012

culpam o Hibernate

A culpa é do Banco de Dados!

Sérgio

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

um SGDB mal configurado pode ser o problema...

Tuesday, August 7, 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

tabelas sem índices

<3Tuesday, August 7, 2012

tabelas sem índices

consultas mal-feitas

<3 <3Tuesday, August 7, 2012

tabelas sem índices

consultas mal-feitas

<3 <3 <3

muitos hits ao banco

Tuesday, August 7, 2012

tabelas sem índices

consultas mal-feitas

muitos hits ao banco

connection leaks

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

tabelas sem índices

consultas mal-feitas

muitos hits ao banco

connection leaks

<3 <3 <3

memory leaks

Tuesday, August 7, 2012

Não saber tirar proveito framework

Tuesday, August 7, 2012

Hibernate Efetivo6 dicas para não deixar

sua app morrer

Tuesday, August 7, 2012

@rponte

Tuesday, August 7, 2012

Tuesday, August 7, 2012

Fortaleza - Terra do SolTuesday, August 7, 2012

#1POOL DE

CONEXÕES

Tuesday, August 7, 2012

com certeza todos aqui já ouviram falar...

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

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

ou até receberem um

Tuesday, August 7, 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

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

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

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

a app volta a funcionar bem por um tempo

Tuesday, August 7, 2012

a app volta a funcionar bem por um tempo

Tuesday, August 7, 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

o pool PADRÃO do Hibernate

Tuesday, August 7, 2012

que possui uma impl. RUDIMENTAR

Tuesday, August 7, 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

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

qual pool utilizar?

Tuesday, August 7, 2012

temos ótimas opções...

Tuesday, August 7, 2012

pools como c3p0 ou commons-dbcp

temos ótimas opções...

Tuesday, August 7, 2012

o Hibernate já vem com c3p0

Tuesday, August 7, 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

ou melhor ainda...

Tuesday, August 7, 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

Pool traz melhoria de performance

Tuesday, August 7, 2012

Pool traz melhoria de performance

mas não faz milagres

Tuesday, August 7, 2012

#2lidando com

LazyInitializationException

Tuesday, August 7, 2012

quando e por que acontece?

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

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

Percorrendo os itens de uma nota

Tuesday, August 7, 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

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

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

resolver parece fácil, certo?

Tuesday, August 7, 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

Mas e quando estamos trabalhando na Web?

Tuesday, August 7, 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

@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

e agora? #comofas

Tuesday, August 7, 2012

e agora? #comofas

Sérgio

passa tudo pra EAGER! ;D

Tuesday, August 7, 2012

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

Tuesday, August 7, 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

mas isso poderia gerar uma sobrecarga...

Tuesday, August 7, 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

lembre-se que ter os relacionamentos como LAZY é

uma boa prática

Tuesday, August 7, 2012

como evitar LIE sem modificar o relacionamento

para EAGER?

Tuesday, August 7, 2012

Open Session In View

Tuesday, August 7, 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

o OSIV só evita LIE no mesmo request!

Tuesday, August 7, 2012

anti-pattern?

Tuesday, August 7, 2012

#3Second Level

Cache

Tuesday, August 7, 2012

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

Carregando uma nota por ID

Tuesday, August 7, 2012

Banco de Dados

Session

Tuesday, August 7, 2012

Banco de Dados

Session

First Level Cache

Tuesday, August 7, 2012

Banco de Dados

Session Session Session Session

Tuesday, August 7, 2012

Banco de Dados

Second Level Cache

Session Session Session Session

Tuesday, August 7, 2012

Banco de Dados

Second Level Cache

Session Session Session Session

First Level Cache

Tuesday, August 7, 2012

Banco de Dados

SessionFactory

Session Session Session Session

Tuesday, August 7, 2012

Configurar é simples

Tuesday, August 7, 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

@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

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE

Tuesday, August 7, 2012

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE

Melhor performance

Tuesday, August 7, 2012

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE

Dados não críticos

Tuesday, August 7, 2012

@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)

Caching Strategy

READ_ONLY

NONSTRICT_READ_WRITE

READ_WRITE Modificações frequentes

Tuesday, August 7, 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

Como 2nd Level Cache funciona?

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

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

somente dos valores das propriedades

Tuesday, August 7, 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

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

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

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

Tuesday, August 7, 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

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

Devo cachear todas as minhas entidades?

Tuesday, August 7, 2012

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

session.load(Issue.class,  17);

Tuesday, August 7, 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

#4Query Cache

Tuesday, August 7, 2012

Query Cache faz cache do resultado de uma query

Tuesday, August 7, 2012

Configurando Hibernate para usar Query Cache

hibernate.cache.use_query_cache=true

hibernate.properties

Tuesday, August 7, 2012

Query Cache

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

Tuesday, August 7, 2012

modelo conceitual do query cache

Query Cache

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

Tuesday, August 7, 2012

modelo conceitual do query cache

Query Cache

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

Query + Parâmetros IDs

Tuesday, August 7, 2012

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

muita ajuda

Tuesday, August 7, 2012

Utilize somente em consultas que são executadas repetidas

vezes com os mesmos parâmetros

Tuesday, August 7, 2012

Utilize somente em consultas que são executadas repetidas

vezes com os mesmos parâmetros

Tuesday, August 7, 2012

#5Select n+1

Tuesday, August 7, 2012

o campeão em prejudicar a performance da

aplicação

Tuesday, August 7, 2012

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

Processando os itens de uma nota

Tuesday, August 7, 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

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

Processando os itens de varias notas

Tuesday, August 7, 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

são muitos hits no banco de dados

Tuesday, August 7, 2012

são muitos hits no banco de dados

mas podemos resolver isso...

Tuesday, August 7, 2012

3 soluções

Tuesday, August 7, 2012

#1 EAGER ou join-fetch

Tuesday, August 7, 2012

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

Utilizando FetchMode=EAGER

Tuesday, August 7, 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

antes de definir um mapeamento global deste

tipo você precisa se perguntar...

Tuesday, August 7, 2012

SEMPRE que uma nota é necessária, todos seus

itens também são necessários?

Tuesday, August 7, 2012

não?Tuesday, August 7, 2012

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

Utilizando Join Fetch

Tuesday, August 7, 2012

#2 batch-size nas associações

Tuesday, August 7, 2012

É o meio termo entre EAGER e LAZY

Tuesday, August 7, 2012

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

@BatchSize

Tuesday, August 7, 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

@BatchSize também é conhecido como:

Tuesday, August 7, 2012

@BatchSize também é conhecido como:

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

Tuesday, August 7, 2012

@BatchSize também é conhecido como:

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

ou seja, é um palpiteTuesday, August 7, 2012

#3 FetchMode SUBSELECT

Tuesday, August 7, 2012

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

SUBSELECT

Tuesday, August 7, 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

Qual utilizar?

Tuesday, August 7, 2012

Qual utilizar?

dependeTuesday, August 7, 2012

#6Processamento

em lote

Tuesday, August 7, 2012

Imagine que temos que importar 100k produtos para

o banco de dados

Tuesday, August 7, 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

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

OutOfMemoryException

Tuesday, August 7, 2012

por que?

Tuesday, August 7, 2012

Hibernate faz cache de todas as instâncias dos Produtos

inseridos na Session

Tuesday, August 7, 2012

mas como melhorar?

Tuesday, August 7, 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

evitamos o OutOfMemoryException

Tuesday, August 7, 2012

evitamos o OutOfMemoryException

Mas o processamento ainda continua lento!

Tuesday, August 7, 2012

evitamos o OutOfMemoryException

Mas o processamento ainda continua lento!

Dá pra melhorar?

Tuesday, August 7, 2012

JDBC puro?

Tuesday, August 7, 2012

JDBC puro?

código de maxu!

Handerson Frota

Tuesday, August 7, 2012

StatelessSession

Tuesday, August 7, 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

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

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

Tuesday, August 7, 2012

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

Yuri Adams

dá pra melhorar?

Tuesday, August 7, 2012

hibernate.jdbc.batch_size=50

hibernate.properties

Tuesday, August 7, 2012

CONCLUSÃO

Tuesday, August 7, 2012

Foi apenas a ponta o iceberg!

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

um DBA certamente pode ter ajudar em muitos cenários

Tuesday, August 7, 2012

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

Tuesday, August 7, 2012

Rafael Ponterponte@triadworks.com.br

Tuesday, August 7, 2012

top related