Réponses:
Le vidage de la session force Hibernate à synchroniser l'état en mémoire du Session
avec la base de données (c'est-à-dire à écrire les modifications dans la base de données). Par défaut, Hibernate effacera automatiquement les modifications pour vous:
Permettre de vider explicitement le Session
donne un contrôle plus fin qui peut être requis dans certaines circonstances (pour obtenir un ID attribué, pour contrôler la taille de la session, ...).
id = session.save(obj);
et la transaction est validée à la ligne suivante mais obj n'est pas sauvegardé à DB, pourquoi? 2) J'ai enregistré obj en utilisant session.save(obj);
avec commit et en retournant j'ai utilisé return obj.getprimaryID();
Dans ce cas, obj est enregistré dans DB. Alors pourquoi ce comportement se produit-il?
Comme indiqué à juste titre dans les réponses ci-dessus, en appelant flush()
nous forçons la mise en veille prolongée à exécuter les commandes SQL sur Database. Mais comprenez que les changements ne sont pas encore «engagés». Donc, après avoir effectué le vidage et avant de faire la validation, si vous accédez directement à la base de données (par exemple à partir de l'invite SQL) et vérifiez les lignes modifiées, vous ne verrez PAS les changements.
Cela revient à ouvrir 2 sessions de commandes SQL. Et les modifications effectuées en 1 session ne sont pas visibles par les autres tant qu'elles ne sont pas validées.
Je sais seulement que lorsque nous appelons session.flush()
nos déclarations sont exécutées dans la base de données mais pas validées.
Supposons que nous n'appelions pas la flush()
méthode sur l'objet session et que si nous appelons la méthode commit, elle effectuera en interne le travail d'exécution des instructions sur la base de données, puis de la validation.
commit=flush+commit
(en cas de fonctionnalité)
Ainsi, je conclus que lorsque nous appelons la méthode flush () sur l'objet Session, alors elle n'obtient pas de validation mais frappe la base de données et exécute la requête et obtient également une restauration.
Afin de s'engager, nous utilisons commit () sur l'objet Transaction.
Le vidage de la session permet de synchroniser les données actuellement dans la session avec ce qui se trouve dans la base de données.
En savoir plus sur le site Web Hibernate:
flush()
est utile, car il n'y a absolument aucune garantie sur le moment où la Session exécute les appels JDBC, seulement l'ordre dans lequel ils sont exécutés - sauf que vous utilisez flush()
.
Vous pouvez utiliser flush
pour forcer la réalisation et la détection des contraintes de validation dans un endroit connu plutôt que lorsque la transaction est validée. Il se peut que cela commit
soit appelé implicitement par une logique de cadre, par une logique déclarative, le conteneur ou par un modèle. Dans ce cas, toute exception levée peut être difficile à attraper et à gérer (elle peut être trop élevée dans le code).
Par exemple, si vous avez save()
un nouvel objet EmailAddress, qui a une contrainte unique sur l'adresse, vous n'obtiendrez pas d'erreur tant que vous ne vous engagez pas.
L'appel flush()
force la ligne à être insérée, lançant une exception en cas de doublon.
Cependant, vous devrez annuler la session après l'exception.
Je voudrais juste regrouper toutes les réponses données ci-dessus et également relier la méthode Flush () à Session.save () afin de donner plus d'importance
Hibernate save () peut être utilisé pour enregistrer l'entité dans la base de données. Nous pouvons invoquer cette méthode en dehors d'une transaction, c'est pourquoi je n'aime pas cette méthode pour enregistrer des données. Si nous utilisons cela sans transaction et que nous avons une cascade entre les entités, alors seule l'entité principale est enregistrée à moins que nous ne vidions la session.
flush (): force la session à vider. Il est utilisé pour synchroniser les données de session avec la base de données.
Lorsque vous appelez session.flush (), les instructions sont exécutées dans la base de données mais elles ne seront pas validées. Si vous n'appelez pas session.flush () et si vous appelez session.commit (), la méthode commit () en interne exécute l'instruction et valide.
Donc commit () = flush + commit. Donc session.flush () exécute simplement les instructions dans la base de données (mais pas les validations) et les instructions ne sont plus EN MÉMOIRE. Cela force simplement la session à rincer.
Quelques points importants:
Nous devons éviter d'enregistrer en dehors des limites de transaction, sinon les entités mappées ne seront pas enregistrées, ce qui entraînera une incohérence des données. Il est très normal d'oublier le vidage de la session car il ne lève aucune exception ni aucun avertissement. Par défaut, Hibernate effacera automatiquement les modifications pour vous: avant certaines exécutions de requêtes lorsqu'une transaction est validée Permettre de vider explicitement la Session donne un contrôle plus fin qui peut être nécessaire dans certaines circonstances (pour obtenir un ID attribué, pour contrôler la taille de la Session )
La flush()
méthode oblige Hibernate à vider la session. Vous pouvez configurer Hibernate pour utiliser le mode de vidage pour la session à l'aide de setFlushMode()
method. Pour obtenir le mode de vidage pour la session en cours, vous pouvez utiliser getFlushMode()
method. Pour vérifier si la session est sale, vous pouvez utiliser isDirty()
method. Par défaut, Hibernate gère le vidage des sessions.
Comme indiqué dans la documentation:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
Rinçage
Le vidage est le processus de synchronisation de l'état du contexte de persistance avec la base de données sous-jacente. Le
EntityManager
et le HibernateSession
exposent un ensemble de méthodes grâce auxquelles le développeur de l'application peut modifier l'état persistant d'une entité.Le contexte de persistance agit comme un cache transactionnel à écriture différée, mettant en file d'attente tout changement d'état d'entité. Comme tout cache d'écriture différée, les modifications sont d'abord appliquées en mémoire et synchronisées avec la base de données pendant le temps de vidage. L'opération de vidage prend chaque changement d'état d'entité et le traduit en une instruction
INSERT
,UPDATE
ouDELETE
.La stratégie de vidage est donnée par le flushMode de la session Hibernate en cours d'exécution. Bien que JPA ne définisse que deux stratégies de rinçage (
AUTO
etCOMMIT
), Hibernate a un spectre beaucoup plus large de types de rinçage:
ALWAYS
: Vide la session avant chaque requête;AUTO
: C'est le mode par défaut et il vide la session uniquement si nécessaire;COMMIT
: La session essaie de retarder le vidage jusqu'à ce que la transaction en cours soit validée, même si elle peut également se vider prématurément;MANUAL
: Le vidage de session est délégué à l'application, qui doit appelerSession.flush()
explicitement pour appliquer les changements de contexte de persistance.Par défaut, Hibernate utilise le
AUTO
mode de vidage qui déclenche un vidage dans les circonstances suivantes:
- avant de valider une transaction;
- avant d'exécuter une requête JPQL / HQL qui chevauche les actions d'entité en file d'attente;
- avant d'exécuter une requête SQL native qui n'a pas de synchronisation enregistrée.
L'appel EntityManager#flush
a des effets secondaires . Il est idéalement utilisé pour les types d'entités avec des valeurs d'ID générées (valeurs de séquence): un tel ID n'est disponible que lors de la synchronisation avec la couche de persistance sous-jacente. Si cet ID est requis avant la fin de la transaction en cours (à des fins de journalisation par exemple), le vidage de la session est requis.