Hibernate: Como diminuir a quantidade de queries realizadas no Hibernate?

12 respostas
T

Ao configurar no Hibernate properties a opção de ‘show_sql = true’ me deparei com a minha aplicação realizando centenas de queries. Mesmo se
inicio os meus relacionamentos 1 to N como lazy, as queries ainda são realizadas.
Gostaria de saber se existe maneira de diminuir este overhead de queries que o hibernates realiza pois estou usando um modelo de dados um tanto quanto complexo (com 1 to n, n to 1, n to n e 1 to 1, não foi usado a abordagem de se iniciar pela modelagem de objetos para a o modelo relacional :frowning: ) e isso esta implicando bastante na performance da aplicação.

12 Respostas

pascoajr

Boa pergunta td_source…heheh também estou nessa situação!!!
quem poderá nos ajudar!?!? :mrgreen:

Abdon

lazy=“true” não resolve??

passos

Nos seus relacionamentos one-to-many set lazy=“true” e sempre que precisar daquela parte da coleção utilize o fetch

<set
            lazy="true"
        >

            <key
                column="...."
            >
            </key>

            <one-to-many
                  class="nomeDaClasse"
            />

        </set>
T

Abdon,

Eu setei todos os relacionamentos possíveis com lazy=true mas mesmo assim, ele continua realizando as queries. Em nenhum momento utilizei o Hibernate.initialize() e mesmo assim, ele realiza as queries… gostaria de saber o porque.

B

Caros amigos, este é um grande problema para quem usa hibernate em aplicações cujo modelo de dados é complexo.

O problema acontece pois sempre que o Hibernate retorna uma entidade A, ela traz também B, C, D e todas as outras associadas.

Quando se usa WebServices, este problema é maior ainda, pois toda vez as entidades tem que ser serializadas e desserializadas, o que é muito custoso para o servidor.

Para resolver este problema, é interessante que sejam removidos os mapeamentos de listas de entidades relacionadas e de objetos relacionados que possuam outros objetos associados.

Convém também fazer consultas mais específicas para os casos onde a baixa performance é facilmente percebida.

exemplo: usa consulta por A gera mais de 100 selects e você só sua alguns campos.
É interessante criar um construtor específico e utilizá-lo para reduzir o processamento.

select new A(A.Codigo, A.Nome, A.Telefone, B.Codigo, B.Descricao) from A, B where A.CodigoB = B.Codigo and A.Nome like '%João%"

Imagine que A é a tabela de clientes de uma locadora e B é a tabela de fitas que ja foram locadas pelo cliente.

Uma consulta por A poderia trazer sempre as 200 fitas que o cliente já locou.

Bem, a princípio é isso aí.
Se quiserem expor seus problemas especificamente, eu tentarei lhes ajudar.

Espero ter ajudado!

B

Quando uma consulta for mto complexa, pode compensar utilizar o jdbc puro mesmo, para nao ter esses problemas…

http://www.hibernate.org/hib_docs/v3/reference/en/html/querysql.html

:wink:

Mauricio_Linhares

O “lazy=true” deve funcionar sempre, talvez tenha alguém acessando essa coleção e vocês não tenham percebido. Mas é sempre bom olhar a documentação:

Improving Performance

bejeto:
Caros amigos, este é um grande problema para quem usa hibernate em aplicações cujo modelo de dados é complexo.

O problema acontece pois sempre que o Hibernate retorna uma entidade A, ela traz também B, C, D e todas as outras associadas.

Nops, isso não é um problema do Hibernate, tudo pode ser definido como "lazy=true’, até mesmo associações 1:1. Se ele está fazendo as queries, é porque está configurado pra fazer.

Qualquer problema, é só abrir um chamado no Jira deles:

http://www.hibernate.org/217.html

T

No meu xml ele está setado como “lazy=true”. Existe algum outro lugar onde isso é configurado?
Então quer dizer que se ele esta realizando queries ele esta carregando os objetos?
Estou com dúvida sobre isso pois já tentei acessar os atributos setados como “lazy=true”, fora do escopo da session, e a exception de ‘LazyInicializationException’ foi lançada… (ou seja, o lazy true ‘funciona’ porém, as queries ainda são feitas).
Não sei se realmente quando ele faz a querie ele carrega ou faz acesso ao objeto. Imagino que seja uma espécie de cash do hibernate.

T

Gostaria de saber como faço pra setar esse tipo de associação (1 to 1) como lazy. Se puder me passar uma referência também agradeceria.

Mauricio_Linhares

Algumas dicas sobre relacionamentos:

http://www.javalobby.org/articles/hibernate-query-101/

O atributo “lazy” pode ter os valores “true”, “false” e “proxy” e existe nos seguintes nós (que eu me lembro agora):

E eu acho que todas as coleções também tem (, e por aí vai).

Também dá pra definir o lazy default no nó , o nome do atributo é “default-lazy”, que pode ser “true” ou “false” (“proxy” é o default se você não definir).

Na referência tem tudo isso.

brunocosta

No Hibernate 3, lazy=true é habilitado por padrão, pra todas as classes, subclasses, joinedclasses, collections e etc,

http://www.hibernate.org/250.html (Procure por Metadata Changes)

o problema parece estar vindo de sua própria aplicação. É algum código que vc tá usando que tá precisando carregar alguma coleção. Um exemplo simples é fazer um “objeto.getColecao().getSize()”, e toda a coleção tem que ser carregada (pra o caso de um Set).

Hammer

bem, eu realmente estou com um problemao, e peskisando aq no forum axei esse topico interessante, talez vcs possam em ajudar

antigamente os meus relacionamentos estavam assim: @ManyToOne(cascade = CascadeType.ALL)

mudei para: @ManyToOne(fetch = FetchType.LAZY), e o ganho de performace foi mt grande, so q eu nao estou conseguindo salvar absolutamente nada no meu banco de dados, so mente salvar, o erro q da eh o seguinte:

diz q uma coluna da tabela(da qual eh a associacao com a outra tabela) nao pode ser null, e realmente nao pode, ele nao esta conseguindo mais fazer essa associação, como posso contornar esse probema?

Criado 19 de julho de 2005
Ultima resposta 29 de ago. de 2007
Respostas 12
Participantes 9