Pergunta

Eu tenho um objeto de domínio Hibernate que é carregado por diferentes partes da aplicação. Às vezes é vantajoso carga preguiçoso cada associação e outros, é melhor carregar a coisa inteira em uma junção. Como compromisso espero feliz que eu encontrei:

Usando busca em lote, o Hibernate pode carregar diversos proxies não inicializados se um proxy é acessado. A busca em lote é uma otimização do seleto estratégia de busca preguiçoso.

hibernate.default_batch_fetch_size :

Usando busca em lote, o Hibernate pode carregar diversos proxies não inicializados se um proxy é acessado. A busca em lote é uma otimização do preguiçoso selecionar estratégia de busca.

Eu também ver:

hibernate.jdbc.fetch_size:

Um valor diferente de zero determina o JDBC buscar tamanho (chama Statement.setFetchSize ()).

Bem é suficiente inteligente Hibernate para olhar no cache de segundo nível ao fazer a busca em lote? i Execute uma busca para a chamada inicial para a associação e, em seguida, as próximas chamadas X atingiu o cache? Dessa forma eu posso ter o carregamento lento que eu desejo, mas também atingiu o cache muitas vezes para o mais volume semelhante transações.

Se todo o conteúdo da coleção já está contido no cache, seria ainda executar as consultas fetching no acesso da coleção?

Graças.

Foi útil?

Solução

Eu fiz um monte de investigação hoje e foi capaz de desenterrar uma resposta à minha pergunta. Eu estava olhando através do código Hibernate e os olhares de fluxo como este:

é a coleção inicializada?

  • Não? Não um lote fetch (itens obtidos por lote-busca são colocados no cache)
  • Sim? Olhada no cache para o item em particular, se ele não está lá fazer um lote-busca.

Portanto, se o item na coleção que você está procurando é encontrado em cache, em seguida, o lote-busca não acontece. Se o item não for encontrado no cache de segundo nível, em seguida, o lote buscar acontece, mas ele vai fazer uma busca de itens em lote, independentemente dos itens em lote estão no cache.


----- ----- EXEMPLO 1

O Bom:

(Três itens de uma coleção - tamanho de lote de 3) O primeiro movimento:

  • collection.getItem (0) - No esconderijo | batch-busca 3 itens
  • collection.getItem (1) - no carregado por lote-fetch
  • collection.getItem (2) - no carregado por lote-fetch

Agora, em outro lugar, mais tarde no tempo:

  • collection.getItem (0) - Hit Cache
  • collection.getItem (1) - Hit Cache
  • collection.getItem (2) - Hit Cache

----- ----- EXEMPLO 2

A Bad:

(Três itens de uma coleção - tamanho de lote de 3)

Neste caso, o item no índice 0 foi removido do cache porque talvez o cache estava cheio e que o item foi descartado, ou o item passou obsoleto ou inativo.

  • collection.getItem (0) - Not In Cache Então Do lote de 3 (??? Select * onde id in (,))
  • collection.getItem (1) - Em cache já (substituído por lote-busca de qualquer maneira)
  • collection.getItem (2) - Em cache já (substituído por lote-busca de qualquer maneira)

Assim, o trade-off aqui é que você terá menos chamadas SQL devido à dosagem, mas você vai estar faltando o cache com mais frequência. Há uma passagem aberta para ter o olhar de lotes no cache de segundo nível antes que ele vai para o banco de dados.

http://opensource.atlassian.com/projects/hibernate/browse / HHH-1775

Vote!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top