À quoi sert session.flush () dans Hibernate


110

Lorsque nous mettons à jour un enregistrement, nous pouvons l'utiliser session.flush()avec Hibernate. De quoi avez-vous besoin flush()?

Réponses:


138

Le vidage de la session force Hibernate à synchroniser l'état en mémoire du Sessionavec 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:

  • avant certaines exécutions de requêtes
  • lorsqu'une transaction est validée

Permettre de vider explicitement le Sessiondonne 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, ...).


8
Notez que cette réponse décrit le comportement de mise en veille prolongée PAR DÉFAUT: le comportement de vidage peut être modifié via le paramètre Mode de vidage. Les détails sont dans docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/… (version 3.5).
SteveT

1
J'ai trouvé le document où il est dit exactement ce que vous dites mais je me demande quelle sera la priorité signifie supposer 1) J'ai une classe dans laquelle j'enregistre l'objet en utilisant le code 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?
Amogh

74

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.


12
Eh bien - les changements peuvent être légèrement visibles. Par exemple, une ligne non validée peut créer un verrou sur la ligne insérée mais non validée et retarder l'insertion de la même ligne par une autre session jusqu'à ce que la transaction soit validée ou annulée. Ce n'est donc pas complètement invisible.
rghome

2
J'ai surfé partout sur le Web et c'est la réponse qui m'a finalement fait comprendre. Merci.
Siddhartha

quelle est l'utilité de mettre .flush () dans une boucle for alors si commit () fait un flush à la fin?
Eildosa le

@Kaushik Lele Quel est le point de flush () si les données ne sont pas visibles après flush? Pouvez-vous élaborer sur certains des cas d'utilisation les plus fins où cela est utile?
java_geek

28

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.


Pouvez-vous donner quelques détails sur le besoin de rinçage?
java_geek

14

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().


Pouvez-vous fournir un scénario dans lequel l'utilisateur devrait s'inquiéter de la séquence? L'utilisation de la mise en veille prolongée consiste à rendre les éléments liés à la base de données transparents pour l'utilisateur. Quand nous faisons "commettre", le vidage se produit automatiquement. Quel est le scénario dans lequel vous ferez un vidage sans vous engager?
Kaushik Lele

1
@KaushikLele vous pouvez vous référer à cette question stackoverflow.com/questions/37382872
...

10

Vous pouvez utiliser flushpour 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 commitsoit 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.


4

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 )


3

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 EntityManageret le Hibernate Sessionexposent 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, UPDATEou DELETE.

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 ( AUTOet COMMIT), 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 appeler Session.flush()explicitement pour appliquer les changements de contexte de persistance.

Par défaut, Hibernate utilise le AUTOmode 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.

1

L'appel EntityManager#flusha 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.


0

Avec cette méthode, vous évoquez le processus de rinçage. Ce processus synchronise l'état de votre base de données avec l'état de votre session en détectant les changements d'état et en exécutant les instructions SQL respectives.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.