Concernant le problème d'hibernation rencontré par mes collègues hier. C'est la chose la plus fondamentale de l'hibernation. Je comprends que de nombreuses personnes ont rencontré ce problème et qu'il est très courant, mais elles deviennent souvent confuses lorsqu'elles le rencontrent.
Afin d'approfondir l'impression, sachez ce que c'est et pourquoi il en est ainsi.
Après cela, j'ai simplement utilisé le framework Hibernate d'origine pour effectuer quelques vérifications, j'ai ouvert la console d'impression SQL d'exécution et je suis arrivé à la conclusion :
Le principe est qu’au milieu d’une même transaction :
1. Utilisez l'instruction SQL, session.createSQLQuery(sql).executeUpdate(); pour insérer, et la station de sortie imprimera l'instruction d'insertion SQL, puis utilisera l'instruction sql pour exécuter session.createSQLQuery(sql).uniqueResult() ; ; et la requête SQL sera également imprimée, il n'y a aucun problème et les données peuvent être interrogées.
2. Utilisez hibernate pour encapsuler l'opération et utilisez session.save(entity); pour insérer la console de sortie n'imprime pas l'instruction SQL insérée. Utilisez ensuite la méthode session.get(entity,id); il n'imprime pas non plus l'instruction de requête SQL, mais les données peuvent être interrogées. Lorsque l'instruction de validation de transaction est exécutée, l'instruction SQL insérée est imprimée
3. Utilisez session.save(entity); d'hibernate pour insérer, puis utilisez l'instruction "HQL" pour interroger. L'effet est le même que celui du deuxième point ci-dessus.
4. Utilisez session.save(entity); d'hibernate pour insérer, mais la console de sortie n'imprime pas l'instruction SQL insérée. Utilisez ensuite l'instruction SQL pour exécuter session.createSQLQuery(sql).uniqueResult(); et l'instruction de requête SQL sera imprimée. Un problème est survenu, aucune donnée n'a pu être interrogée. Dans ce cas, utilisez la méthode session.flush(), exécutez la méthode flush() avant d'interroger et la console de sortie imprimera l'instruction SQL insérée. Si vous interrogez à nouveau, vous aurez des données.
Une fois la vérification terminée, j'ai vérifié les informations ci-dessus. Concernant le quatrième point, il est apparu fréquemment au cours du processus de développement. Je pense que beaucoup de gens l'ont rencontré, mais beaucoup de gens continuent d'être confus. Cela n’a fait qu’approfondir l’impression.
Depuis la console d'impression SQL, nous pouvons voir le processus de fonctionnement d'une méthode de sauvegarde de base en veille prolongée :
1. Déterminez si l'instance à sauvegarder est déjà dans un état persistant, et sinon, placez-la dans le cache ;
2. Planifiez une instruction insert sql basée sur l'instance à enregistrer. Notez qu'elle est uniquement planifiée et non exécutée ;
3. L'instruction d'insertion précédemment planifiée est exécutée lorsque la transaction est validée ;
Remplacez tx.commit() par session.flush À ce stade, le contrôle imprime l'instruction d'insertion, mais aucun nouvel enregistrement n'est ajouté à la base de données ;
La fonction principale de la méthode flush est de nettoyer le cache et de forcer la base de données à se synchroniser avec le cache Hibernate pour garantir la cohérence des données. Son action principale est d'envoyer une série d'instructions SQL à la base de données et d'exécuter ces instructions SQL, mais il ne les soumettra pas à la base de données. La méthode commit appellera d’abord la méthode flush, puis validera la transaction. C'est pourquoi l'enregistrement n'est pas inséré dans la base de données lorsque nous appelons simplement flush, car les mises à jour de la base de données ne seront enregistrées que lorsque la transaction sera validée. Étant donné que la méthode commit appelle implicitement flush, nous n’appelons généralement pas explicitement la méthode flush.
C'est le mécanisme de vidage d'hibernation. Lors du processus de mise à jour et de sauvegarde de certains objets complexes, il est nécessaire de déterminer si les changements dans l'ordre des opérations de la base de données et si les vidages retardés ont un impact sur les résultats du programme. S'il y a effectivement un impact, vous pouvez ajouter un vidage là où vous devez maintenir l'ordre des opérations pour forcer Hibernate à vider les opérations enregistrées dans le cache dans la base de données. Cela n'a peut-être pas l'air joli, mais c'est très efficace.
Question : La méthode session.save est placée dans le cache et ne peut pas être trouvée par SQL interrogeant directement la base de données.
Après la méthode flush(), le SQL exécuté sera imprimé, mais il n'est toujours pas dans la base de données. Une requête SQL directe peut trouver les données.
1. Où les données d'entité sont-elles stockées après flush() ? Le cache est le même que la méthode save(), donc SQL ne devrait pas pouvoir l'obtenir.
2. Étant donné que les données ne sont pas entrées dans la base de données après la méthode de vidage, SQL peut être directement interrogé en utilisant session.createSQLQuery(sql) pour interroger. Il convient de vérifier directement qu'il ne s'agit pas de la base de données. Quel est l'endroit où il interroge ?