Hibernate Objetos de cache do 2º nível que são preguiçosos = false, resultam em uma busca padrão = junção, está documentado em qualquer lugar?

StackOverflow https://stackoverflow.com/questions/1968767

Pergunta

Eu experimento a seguinte questão aparentemente indocumentada e quero entender se

  1. eu fiz algo errado
  2. Alguém encontrou o mesmo problema?
  3. Realmente não está documentado em nenhum lugar? Ou eu perdi alguma coisa?

O comportamento é que isso assuma o seguinte mapeamento

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar"/>
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    ...
</class>

Primeiro, como pano de fundo, o valor padrão de hiberna para o buscar atributo em uma relação muitos para um deve ser "Selecione", Isso é pelo menos o que está documentado (vou adicionar o link aqui quando o encontrar)

No entanto, isso aparentemente é verdade apenas se a classe referenciada for preguiçosa = "verdadeiro"!

Então, aparentemente, o mapeamento acima é traduzido para isso (porque a barra é preguiçosa = "falsa"):

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    ...
</class>

Agora, por que isso seria um problema? Em vez de 2 seleciona, o Hibernate carregará a referência não preguiçosa em uma única seleção com seu "pai" (carregue foo com barra em uma única seleção)

Isso realmente faz sentido, já que o objeto não é preguiçoso, por que não carregá -lo?

A resposta é a seguinte: o que acontece se a barra estiver no cache do 2º nível?

<class name="org.sample.Foo" table="foo">
    ...
   <many-to-one name="bar" class="org.sample.Bar" *fetch="join" />
</class>


<class name="org.sample.Bar" table="bar" lazy="false">
    <cache usage="transactional" />
    ...
</class>

E a resposta para isso é - nada muda!

Aparentemente, seria de assumir que o Hibernate é inteligente o suficiente para entender que os objetos desse tipo não devem ser carregados, mas como a busca padrão foi alterada de seleção para ingressar, o Hibernate não tem escolha (você não pode se juntar a uma tabela real com o 2º cache de nível ainda)

Portanto, o Hibernate faz o que é dito e usa uma junção para buscar um objeto no banco de dados onde ele já está no 2º cache de nível

A solução que encontrei é literalmente mudar o mapeamento para buscar = "selecionar"

Agora, quando a segunda seleção para bar está prestes a ir, o Hibernate entende que não deve ir ao banco de dados e buscá -lo no cache. e apenas 1 consulta será executada (após o aquecimento)

Foi útil?

Solução

Encontrei o mesmo problema e me vi marcando todas as relações muitos para um que serão armazenados em cache como fetch="select". No momento em que a consulta é construída, o Hibernate não pode saber se a instância solicitada da barra está no cache de segundo nível ou não (supondo que o foo não esteja em cache).

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