Mise en veille prolongée 2e objets de cache de niveau qui sont paresseux = false, se traduisent par un défaut fetch = joindre, est-il documenté nulle part?

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

Question

Je l'expérience de la question apparemment sans papier suivant, et je veux comprendre si

  1. Je l'ai fait quelque chose de mal
  2. Est-ce que quelqu'un rencontre le même problème?
  3. Est-il vraiment pas documenté nulle part? ou ai-je raté quelque chose?

Le comportement est-ce Supposons que le mappage suivant

<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>

Tout d'abord, en arrière-plan, Hibernate valeur par défaut pour chercher attribut sur un grand nombre à une relation devrait être « sélectionnez », cela est au moins ce qui est documenté (je vais ajouter le lien ici quand je trouve)

Cependant, cela est apparemment vrai que si la classe référencée est paresseux = "true"!

donc apparemment la correspondance ci-dessus se traduit dans ce (parce que Bar est paresseux = "false"):

<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>

Maintenant, pourquoi serait-ce un problème? au lieu de 2 sélectionne, Hibernate va charger la référence non paresseux dans un seul sélectionner avec son « parent » (charge Foo Bar avec une seule sélection)

fait réellement sens, puisque l'objet est pas paresseux, pourquoi ne pas le charger?

La réponse est la suivante: ce qui se passe si la barre est dans le cache de niveau 2

?
<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>

Et la réponse à cette question est - change rien

Apparemment, on peut supposer Hibernate est assez intelligent pour comprendre que les objets de ce type ne devraient pas être chargées, mais étant donné que la valeur par défaut a été changé de chercher à se joindre select, Hibernate ne dispose pas d'un choix (vous ne pouvez pas joindre un vrai table avec le cache de niveau 2, encore)

Mise en veille prolongée fait ce qu'il est dit, et utilise une jointure pour aller chercher un objet à partir de la base de données où il est déjà dans le cache de niveau 2

La solution que je trouve est de changer littéralement la mise en correspondance pour aller chercher = « select »

Maintenant, quand la deuxième sélection pour Bar est sur le point d'aller, Hibernate comprend qu'il ne doit pas aller à la base de données, et il récupère à partir du cache. et seulement 1 requête exécutera (après warm-up)

Était-ce utile?

La solution

Je rencontrais la même question, et moi-même trouvé le marquage de tous plusieurs à une relation qui seront mises en cache comme fetch="select". Au moment où la requête est construite, Hibernate ne peut pas savoir si l'instance demandée Bar est dans le cache de second niveau ou non (en supposant que Foo est pas mises en cache).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top