Liste des États

Et maintenant, le plaisir commence. Nous étudierons les états des objets Entity. Vous devez payer pour tout, et pour utiliser Hibernate aussi. Ne pensez-vous pas qu'apprendre HQL est un tel prix ? Non, la vie est un peu plus compliquée.

Si vous avez une sorte d'objet Entity que vous pouvez enregistrer dans la base de données à l'aide d'Hibernate, alors du point de vue d'Hibernate, cet objet peut avoir quatre états :

  • Transitoire
  • Persistant (ou géré)
  • Détaché
  • Supprimé

Et pour vous intéresser, je vais ajouter cette image à cette conférence :

Transitoire

En fait, tout est beaucoup plus simple qu'il n'y paraît, mais pas sans nuances. Par exemple, chaque objet Entity que vous avez explicitement créé à l'aide du code Java et que vous n'avez pas chargé à partir de la base de données à l'aide d'Hibernate a un statut Transient (transparent).

EmployeeEntity employee = new EmployeeEntity();

Le statut Transient signifie qu'Hibernate n'a aucune idée de cet objet, et aucune action sur l'objet n'affecte Hibernate, pas plus que le travail d'Hibernate sur cet objet.

Ces objets sont également appelés POJO - Plain Old Java Object . Le terme est souvent utilisé comme le contraire de divers objets au comportement délicat. Vous souvenez-vous des objets Moc créés par Mockito ? Ici, ce ne sont pas des POJO.

Si du code client fonctionne avec un objet avec le statut Transitoire, alors leur interaction peut être décrite par un schéma super simple :

Persistant ou géré

Le deuxième cas le plus courant concerne les objets liés au moteur Hibernate. Leur statut est appelé Persistant (ou Géré). Il existe exactement deux façons d'obtenir un objet avec ce statut :

  • Charger l'objet depuis Hibernate.
  • Enregistrer l'objet dans Hibernate.

Exemples:

Employee employee = session.load(Employee.class, 1);
Employee employee = new Employee ();
session.save(employee);

Un tel objet correspond généralement à une sorte d'enregistrement dans la base de données, il a un ID et similaire. Cet objet est attaché à la session Hibernate, et en général peut être représenté non pas par un objet réel, mais par une sorte de proxy.

Il est tout à fait possible qu'après avoir appelé la méthode session.load() , vous récupériez un objet stub (proxy), et tous les appels à la base de données ne seront effectués qu'après avoir appelé les méthodes de cet objet. Mais nous parlerons de ces détails un peu plus tard.

Et l'interaction entre le code client et l'objet dans le statut Géré peut être décrite avec l'image suivante :

Détaché

L'état suivant est lorsque l'objet a été détaché de la session. Autrement dit, une fois que l'objet a été attaché à la session Hibernate, mais la session a été fermée ou la transaction terminée, et Hibernate ne surveille plus cet objet.

Exemple:

session.close();
session.evict(entity);

Dans le premier exemple, la session était fermée. Dans le second cas, nous avons explicitement indiqué que nous voulions détacher l'objet de la session à l'aide de la méthode evict() .

Le nouveau schéma d'interaction code-objet ressemblera à ceci :

Et c'est là que ça devient intéressant. Si votre objet a été obtenu à partir d'Hibernate, il est probable que vous ayez reçu un proxy au lieu d'un objet réel. Et cet objet proxy, après s'être déconnecté de la session, lèvera des exceptions lorsque ses méthodes seront appelées.

C'est le problème le plus courant pour tous les débutants lorsqu'ils travaillent avec Hibernate. Vous devez connaître exactement à tout moment la réponse à des questions comme celle-ci lorsque vous travaillez avec un objet Entity :

  • Avez-vous un objet réel ou juste un proxy d'un objet réel ?
  • Êtes-vous actuellement en transaction ou non ?
  • S'agit-il d'une transaction en lecture-écriture ou d'une transaction en lecture seule ?
  • L'objet est-il géré par le mécanisme LazyLoading ?
  • Quelles parties de l'objet sont déjà chargées en mémoire et quelles parties seront chargées lors de l'accès ?
  • Comment votre objet est-il connecté aux objets dépendants ?

La bonne nouvelle est que la plupart du temps, c'est évident. Mais encore faut-il comprendre comment tout cela fonctionne sous le capot. La programmation déclarative est ce qu'elle est - vous pouvez écrire du code en 10 minutes, comprendre pourquoi cela ne fonctionne pas comme il se doit - en 10 heures :)

Supprimé

Et le dernier état que votre objet Entity peut avoir est Supprimé. Comme vous l'avez probablement déjà deviné d'après son nom, il s'agit de l'état d'un objet distant.

Cet état apparaît en raison du fait que si vous supprimez un objet de la base de données, l'objet Java ne disparaîtra pas immédiatement n'importe où.

Employee employee = session.load(Employee.class, 1);
//after loading the object's state is Persisted

session.remove(employee);
//after deletion, the state of the object is Removed

session.save(employee);
//and now Persisted again

session.close();
//and now the Detached state