Elenco degli Stati

E ora inizia il divertimento. Studieremo gli stati degli oggetti Entity. Devi pagare per tutto e anche per l'utilizzo di Hibernate. Non pensi che imparare HQL sia un tale prezzo? No, la vita è un po' più complicata.

Se hai una sorta di oggetto Entity che puoi salvare nel database usando Hibernate, quindi dal punto di vista di Hibernate, questo oggetto può avere quattro stati:

  • Transitorio
  • Persistente (o gestito)
  • Distaccato
  • RIMOSSO

E per interessarti, aggiungerò questa immagine a questa conferenza:

Transitorio

In effetti, tutto è molto più semplice di quanto sembri, anche se non privo di sfumature. Ad esempio, ogni oggetto Entity che hai creato in modo esplicito utilizzando il codice Java e che non hai caricato dal database utilizzando Hibernate, ha uno stato Transient (trasparente).

EmployeeEntity employee = new EmployeeEntity();

Lo stato transitorio significa che Hibernate non ha idea di questo oggetto e nessuna azione sull'oggetto influisce su Hibernate, né il lavoro di Hibernate su questo oggetto.

Tali oggetti sono anche chiamati POJO - Plain Old Java Object . Il termine è spesso usato come l'opposto di vari oggetti con un comportamento ingannevole. Ricordi gli oggetti Moc creati da Mockito? Qui non sono POJO.

Se un codice client funziona con un oggetto con lo stato Transient, la loro interazione può essere descritta da uno schema semplicissimo:

Persistente o Gestito

Il prossimo caso più comune sono gli oggetti relativi al motore Hibernate. Il loro stato è chiamato Persistente (o Gestito). Ci sono esattamente due modi per ottenere un oggetto con questo stato:

  • Carica l'oggetto da Hibernate.
  • Salva oggetto in ibernazione.

Esempi:

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

Tale oggetto di solito corrisponde a una sorta di record nel database, ha un ID e simili. Questo oggetto è collegato alla sessione di ibernazione e in generale può essere rappresentato non da un oggetto reale, ma da una sorta di proxy.

È del tutto possibile che dopo aver chiamato il metodo session.load() , si otterrà un oggetto stub (proxy) e tutte le chiamate al database verranno eseguite solo dopo aver chiamato i metodi di questo oggetto. Ma parleremo di tali dettagli un po 'più tardi.

E l'interazione tra il codice client e l'oggetto nello stato Gestito può essere descritta con la seguente immagine:

Distaccato

Lo stato successivo è quando l'oggetto è stato scollegato dalla sessione. Cioè, una volta che l'oggetto è stato collegato alla sessione di ibernazione, ma poi la sessione è stata chiusa o la transazione è terminata e Hibernate non monitora più questo oggetto.

Esempio:

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

Nel primo esempio, la sessione è stata chiusa. Nel secondo caso, abbiamo esplicitamente indicato di voler staccare l'oggetto dalla sessione utilizzando il metodo evict() .

Il nuovo schema di interazione codice-oggetto sarà simile al seguente:

Ed è qui che diventa interessante. Se il tuo oggetto è stato ottenuto da Hibernate, è probabile che ti sia stato fornito un proxy anziché un oggetto reale. E questo oggetto proxy, dopo essersi disconnesso dalla sessione, genererà eccezioni quando vengono chiamati i suoi metodi.

Questo è il problema più comune per tutti i principianti quando lavorano con Hibernate. Devi sapere esattamente in qualsiasi momento la risposta a domande come questa quando lavori con un oggetto Entity :

  • Hai un oggetto reale o solo un proxy da un oggetto reale?
  • Sei attualmente in una transazione o no?
  • È una transazione di lettura-scrittura o una transazione di sola lettura?
  • L'oggetto è gestito dal meccanismo LazyLoading?
  • Quali parti dell'oggetto sono già caricate in memoria e quali parti verranno caricate all'accesso?
  • In che modo il tuo oggetto è connesso agli oggetti dipendenti?

La buona notizia è che la maggior parte delle volte è ovvio. Ma devi ancora capire come funziona tutto sotto il cofano. La programmazione dichiarativa è quello che è: puoi scrivere codice in 10 minuti, capire perché non funziona come dovrebbe - in 10 ore :)

RIMOSSO

E l'ultimo stato che il tuo oggetto Entity può avere è Removed. Come probabilmente hai già intuito dal suo nome, questo è lo stato di un oggetto remoto.

Questo stato appare a causa del fatto che se elimini un oggetto dal database, l'oggetto Java non scomparirà immediatamente da nessuna parte.

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