Lista över stater

Och nu börjar det roliga. Vi kommer att studera tillstånden för Entitetsobjekt. Du måste betala för allt, och för att använda Hibernate också. Tycker du inte att det är ett sådant pris att lära sig HQL? Nej, livet är lite mer komplicerat.

Om du har något slags Entity-objekt som du kan spara till databasen med hjälp av Hibernate, kan det här objektet ha fyra tillstånd från Hibernate-synpunkt:

  • Övergående
  • Beständig (eller hanterad)
  • Friliggande
  • Tog bort

Och för att intressera dig kommer jag att lägga till den här bilden till denna föreläsning:

Övergående

Faktum är att allt är mycket enklare än det verkar, men inte utan nyanser. Till exempel har varje Entity-objekt som du uttryckligen skapat med Java-kod, och inte laddade från databasen med Hibernate, en Transient (transparent) status.

EmployeeEntity employee = new EmployeeEntity();

Statusen Transient betyder att Hibernate inte har någon aning om detta objekt, och ingen åtgärd på objektet påverkar Hibernate, inte heller Hibernates arbete med detta objekt.

Sådana objekt kallas även POJO - Plain Old Java Object . Termen används ofta som motsatsen till olika föremål med knepigt beteende. Kommer du ihåg Moc-objekten som Mockito skapade? Här är de inte POJO.

Om någon klientkod fungerar med ett objekt med Transient-status, kan deras interaktion beskrivas med ett superenkelt schema:

Beständig eller hanterad

Det näst vanligaste fallet är objekt relaterade till Hibernate-motorn. Deras status kallas Persistent (eller Managed). Det finns exakt två sätt att få ett objekt med denna status:

  • Ladda objekt från Hibernate.
  • Spara objekt i Hibernate.

Exempel:

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

Ett sådant objekt brukar motsvara någon sorts post i databasen, det har ett ID och liknande. Detta objekt är kopplat till Hibernate-sessionen och kan i allmänhet inte representeras av ett verkligt objekt, utan av någon sorts proxy.

Det är mycket möjligt att efter att ha anropat session.load()- metoden får du tillbaka något stubobjekt (proxy), och alla anrop till databasen kommer att utföras först efter att metoderna för detta objekt har anropats. Men vi kommer att prata om sådana detaljer lite senare.

Och interaktionen mellan klientkoden och objektet i hanterad status kan beskrivas med följande bild:

Friliggande

Nästa tillstånd är när objektet har kopplats bort från sessionen. Det vill säga när objektet var kopplat till Hibernate-sessionen, men sedan stängdes sessionen eller transaktionen avslutades, och Hibernate övervakar inte längre detta objekt.

Exempel:

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

I det första exemplet stängdes sessionen. I det andra fallet har vi uttryckligen angett att vi vill koppla bort objektet från sessionen med metoden evict() .

Det nya kod-objekt-interaktionsschemat kommer att se ut så här:

Och det är här det blir intressant. Om ditt objekt erhölls från Hibernate, är det troligt att du fick en proxy istället för ett riktigt objekt. Och detta proxyobjekt kommer, efter att ha kopplats från sessionen, att skapa undantag när dess metoder anropas.

Detta är det vanligaste problemet för alla nybörjare när de arbetar med Hibernate. Du måste veta exakt när som helst svaret på frågor som denna när du arbetar med ett Entity-objekt :

  • Har du ett riktigt objekt eller bara en proxy från ett riktigt objekt?
  • Är du för närvarande i en transaktion eller inte?
  • Är det en läs-skrivtransaktion eller en skrivskyddad transaktion?
  • Hanteras objektet av LazyLoading-mekanismen?
  • Vilka delar av objektet är redan inlästa i minnet, och vilka delar kommer att laddas när de öppnas?
  • Hur är ditt objekt kopplat till beroende objekt?

Den goda nyheten är att det oftast är uppenbart. Men du måste fortfarande förstå hur det hela fungerar under huven. Deklarativ programmering är vad det är - du kan skriva kod på 10 minuter, förstå varför det inte fungerar som det ska - på 10 timmar :)

Tog bort

Och det sista tillståndet ditt Entity-objekt kan ha är Removed. Som du förmodligen redan gissat utifrån namnet är detta tillståndet för ett fjärrobjekt.

Detta tillstånd visas på grund av det faktum att om du tar bort något objekt från databasen, kommer Java-objektet inte omedelbart att försvinna någonstans.

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