Comment Hibernate détecte-t-il l'état sale d'un objet entity?

Utilise-t-il une sorte de modification des codes d'octets aux classes d'origine?

Ou, peut-être Hibernate obtenir l'état sale en comparant l'objet donné avec la version précédemment persistante?

J'ai un problème avec les méthodes hashCode() et equals() pour les objets compliqués. Je pense qu'il serait très lent de calculer le code de hachage si l'objet a des membres de collection, et les références cycliques sont également un problème.

Si Hibernate n'utilise pas hashCode()/equals() pour vérifier l'état sale, je je suppose que je ne devrais pas utiliser equals()/hashCode() pour l'objet entity (pas l'objet value), mais j'ai aussi peur que le même opérateur (==) ne soit pas suffisant.

Donc, les questions sont:

  1. Comment Hibernate savoir si une propriété d'un objet est modifié?

  2. Suggérez-vous de remplacer le hashCode()/equals() méthodes pour les objets compliqués? Que faire s'ils contiennent des références cycliques?

    Et

  3. Serait hashCode()/equals() avec seulement l' id champ assez?

51
demandé sur Vlad Mihalcea 2011-03-11 05:54:08

4 réponses

Hibernate utilise une stratégie appelée inspection, qui est essentiellement la suivante: lorsqu'un objet est chargé à partir de la base de données, un instantané de celui-ci est conservé en mémoire. Lorsque la session est vidée, Hibernate compare l'instantané stocké avec l'état actuel. S'ils diffèrent, l'objet est marqué comme sale et une commande SQL appropriée est mise en file d'attente. Si l'objet est toujours transitoire, il est toujours sale.

Source: book Hibernate en Action (annexe B: implémentation ORM stratégies)

Il est important de noter cependant que la vérification sale D'Hibernate est indépendante des méthodes equals / hascode . Hibernate ne regarde pas du tout ces méthodes (sauf lors de l'utilisation de java.util.Ensemble, mais cela n'est pas lié à la vérification sale, seulement à L'API Collections) l'instantané d'état que j'ai mentionné plus tôt est quelque chose de similaire à un tableau de valeurs. Ce serait une très mauvaise décision de laisser un tel aspect fondamental du framework entre les mains des développeurs (à être honnête, les développeurs ne devraient pas se soucier de sale-vérification). Inutile de dire que equals/hascode peut être implémenté de plusieurs façons en fonction de vos besoins. Je vous recommande de lire le livre cité, là l'auteur discute des stratégies d'implémentation equals/hascode. Lecture très perspicace.

90
répondu Antonio 2016-11-17 20:11:21

Hibernate default dirty checking mechanism fera correspondre toutes les propriétés mappées de toutes les entités actuellement attachées à leurs valeurs initiales de temps de chargement.

Vous pouvez mieux visualiser ce processus dans le diagramme suivant:

Vérification sale automatique par défaut

16
répondu Vlad Mihalcea 2018-01-04 11:57:41

Hibernate effectue une vérification champ par champ pour déterminer la saleté d'une entité.

Donc hashCode / equals ne viennent pas dans l'image du tout.

En fait, la vérification sale champ par champ effectuée par Hibernate peut être très coûteuse en termes de performances.

Il fournit donc des interfaces comme la stratégie ou L'intercepteur.findDirty() pour gérer la même chose.

Après le post explique cela plus en détail (avec quelques idées pour les applications à optimiser il entièrement): http://prismoskills.appspot.com/lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp

6
répondu user2250246 2014-07-06 23:36:30

C'est simple-lorsque vous chargez/obtenez l'objet entity par id, puis définissez ses nouvelles valeurs de champ par la méthode setter et fermez la session sans appeler la méthode update () . ensuite, hibernate met à jour automatiquement la valeur modifiée dans la table sans affecter les autres champs. et en même temps, l'objet entity est dans un état sale .

-2
répondu vishal thakur 2017-11-23 06:35:20