liée à cette Question < / a> Premisse: strong> P> Ce sont mes hypothèses, basées sur ma lecture, mon expérience et votre compréhension, ils peuvent avoir tort, s'ils le sont, veuillez commenter et je ' ll Modifier la question. p> question: strong> p> J'ai un objet qui n'est pas dans le cache de 2e niveau. En raison de la mauvaise programmation ou d'autres contraintes, le code qui charge l'objet est appelé plusieurs fois dans la même session hibernate. La rétravale utilise une requête HQL Trouver
par exemple. p> Avant d'ajouter le cache de requête, si le code ci-dessus a été appelé n Times dans la même session hibernate, il y avait des hits sur la base de données p> alors je voulait voir ce qui se passe si j'ajoute la cache de requête: p> Lorsque j'ai ajouté la cache de requête, j'ai remarqué que pendant la même session, hibernate ne frappe pas la base de données n fois plus encore, une fois par session. p> Au fait, dans le question"> question est affirmée que la cache de requête ne fonctionne pas sur la portée du cache de session. Suis-je mis en place cette revendication ou autre chose? P> P>
foo code>) qui ne figure pas dans le cache de 2e niveau, a été modifié dans la base de données, puis la mise en cache de requête, la session croisée, retournera les mauvais identifiants, et donc les mauvais objets. Est-ce correct? Li>
3 Réponses :
seuls hypothèses em> strong>: p>
Selon ce article de Documentation hibernate: P>
[cache de requête] crée deux nouvelles cachees
Régions: une requête mise en cache
ensembles de résultats
(org.hibernate.cache.tandardquerycache),
l'autre tenant des horodatages de la
Mises à jour les plus récentes d'interrogateur
les tables
(org.hibernate.cache.updatetestampstache). P>
blockQuote>
Je suppose que cela signifie que chaque fois que l'horodatage de la table requérable est plus récent que le nombre de résultats - il provoquera l'approche de la DB dans le prochain appel à cette requête et que ce qui garde le cache de requête en sécurité dans certains aspect. p>
Mais 2 phrases plus tard dans le même paragraphe de la documentation, il est indiqué: p>
Le cache de requête doit toujours être utilisé
En conjonction avec le deuxième niveau
cache. p>
blockQuote>
Encore une fois, mon hypothèse est que c'est la seule façon dont Hibernate peut être conscient des modifications apportées à la base de données qui sont effectuées hors de cette session spécifique de l'utilisateur P>
Un cache de requête est un type particulier de cache de 2e niveau. Ce que vous faites référence au cache de 2e niveau, je préférerais appeler "cache d'objet". P>
Commentaires sur vos hypothèses: P>
- La cache de requête est bonne surtout avec le cache de 2e niveau (objet AKA cache). em> li> ul> blockQuote>
Un cache de requête ne contient que les résultats bruts des requêtes en tant que touches primaires, dans Hibernate Speak, ID's. Il ne tient pas les objets hydratés réels. Cela est logique que lorsque vous exécutez une requête avec JDBC, cela ne vous donne que des objets hydratés (peuplés) à la suite de votre itération sur les Resultats. La déclaration n'est pas nécessairement correcte. Si la requête est très compliquée et prend donc très longtemps à courir, en utilisant un cache de requête, vous économiserez ce temps. En utilisant un cache de requête, vous ne économiserez pas le temps nécessaire pour charger les objets de la base de données. P>
- la cache de requête est risquée si la base de données a été modifiée et que cela n'a pas été reflété au cache em> li> ul> blockQuote>
Ceci est vrai, mais il n'est pas unique d'interroger le cache, il en va de même pour ce que vous avez terminé le cache de 2e niveau, mais ce qui est typiquement appelé cache d'objet. P>
alors ma première hypothèse est que Hibernate d'abord des recherches dans le Cache de session, puis au 2e niveau Cache. Cette hypothèse est-elle correcte? Em> p> blockQuote>
Oui, lors du chargement d'objets, c'est le comportement. P>
je suppose aussi que si l'objet (foo) qui n'est pas dans le cache du 2e niveau, a été changé dans la base de données, puis Cache de requête, session croisée Scoped, retournera le mauvais identificateurs, et donc le mauvais objets. Est-ce correct? Em> p> blockQuote>
Oui, à la fois le cache d'objet et le cache de requête seront affectés. Ceci n'est que de préoccupation si la base de données est modifiée sans aller via hibernate. Vous pouvez potentiellement atténuer l'effet de cela en définissant le délai d'attente du cache de requête. P>
est-il alors sûr de dire que l'utilisation de cache de requête pour les requêtes qui incluent informations immuables même pour non 2L Objets mis en cache, est une bonne pratique? (par ex. une question que sa clause où contient une condition qui sera toujours renvoyer les mêmes résultats, par exemple "sélectionner p.ser_num où p.id =? "Quand ser_num et les couples ID ne changent pas une fois créé) p> blockQuote>
Pour ce type d'objets, il n'y a aucune raison de ne pas utiliser à la fois un cache d'objet et un cache de requête. P>
et oui, la mise en cache de requête ne fonctionne pas au niveau de la session AKA Niveau 1 Cache. Ainsi, la raison pour laquelle lorsque vous exécutez la requête à nouveau, il frappe à nouveau la base de données. Il ne mettra pas le résultat (ID SET) d'une requête dans le cache de session. P>
Merci pour la réponse très approfondie, une chose que je ne comprends pas. Lorsque vous avez écrit ", il ne mettra pas le résultat (jeu d'identité) d'une requête dans le cache de session." - Quand il "frappe la base de données à nouveau", exécute-t-il la requête telle quelle? Ou charte simplement les objets par ID dans une requête "Sélectionner dans"? Lorsque la portée de la session est terminée, le cache de requête doit toujours tenir les ID, même s'ils sont d'un objet non dans le cache du 2e niveau, non?
Si la requête n'est pas une requête mise en cache, elle frappera la base de données à chaque fois (la requête complète), comme vous l'avez vu. S'il est configuré pour mettre en cache, il frappera la base de données la première fois et non. Ce que je vous suggère de faire est d'activer la journalisation SQL par le paramètre hibernate ou par définition org.hibernate.sql vers le débogage afin que vous puissiez voir exactement quand il frappe la base de données.
Pour votre question n ° 3, je ne pense pas que vous souhaitiez utiliser le cache de requête lorsque les objets ne sont pas mis en cache. Vous vous retrouverez avec tous les identifiants principaux, mais il devra frapper la base de données une fois par clé pour récupérer les objets pouvant être plus lents que d'exécuter la requête sans cache du tout. À partir de 3,3 de toute façon, peut-être dans les versions plus récentes, il attrape les objets manquants en utilisant moins de requêtes, par exemple. où id in (: ID1,: id2, ...). p>
+1 pour une question excellemment formée, formatée et recherchée.