web-dev-qa-db-fra.com

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

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

Ou, Hibernate peut-il 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 du 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 suppose que je ne devrais pas utiliser equals()/hashCode() pour le objet entité (pas objet valeur), mais j'ai aussi peur si le même opérateur (==) ne suffit pas.

Donc, les questions sont:

  1. Comment Hibernate sait-il si une propriété d'un objet est modifiée?

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

    Et aussi,

  3. Est-ce que hashCode()/equals() avec seulement le champ id serait suffisant?

58
Xiè Jìléi

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é à 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 encore transitoire, il est toujours sale.

Source: livre Hibernate in Action (annexe B: Stratégies de mise en œuvre de l'ORM)

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.Set, mais cela n'est pas lié à la vérification de la saleté, uniquement à l'API Collections) L'instantané d'état que j'ai mentionné précédemment est quelque chose de similaire à un tableau de valeurs. Ce serait une très mauvaise décision de laisser un tel aspect central du framework entre les mains des développeurs (pour être honnête, les développeurs ne devraient pas se soucier du sale contrôle). Inutile de dire que equals/hascode peut être implémenté de plusieurs façons selon vos besoins. Je vous recommande de lire le livre cité, là, l'auteur discute des stratégies de mise en œuvre d'égaux/hascode. Lecture très perspicace.

93
Antonio

mécanisme de vérification par défaut de mise en veille prolongée correspondra à toutes les propriétés mappées de toutes les entités actuellement attachées par rapport à leurs valeurs initiales de chargement.

Vous pouvez mieux visualiser ce processus dans le diagramme suivant:

Default automatic dirty checking

18
Vlad Mihalcea

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

Donc, hashCode/equals n'apparaissent pas du tout dans l'image.

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

Il fournit donc des interfaces comme Strategy ou Interceptor.findDirty () pour gérer la même chose.

Le post suivant explique cela plus en détail (avec quelques idées d'applications pour optimiser entièrement): http://prismoskills.appspot.com /lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp

7
user2250246