Eliminarea cu metoda remove().

În cele din urmă, să ne uităm la ștergerea unui obiect. În principiu, ștergerea obiectelor din baza de date este foarte simplă, dar după cum se spune, există nuanțe. Și există șase astfel de nuanțe:

  • Eliminarea cu metoda remove().
  • Eliminare pentru companie
  • Eliminare de către orfan
  • Ștergeți cu JPQL
  • Ștergerea prin NativeQuery
  • softDeleted()

Și vom începe cu cea mai evidentă soluție - apelarea metodei remove() .

User user = new User();
user.setName("Kolyan");
session.persist(user);  // add an object to the database
session.flush();
session.clear();  // close the session

user = (User) session.find(User.class, user.getId() ); //receive the object from the database
session.remove(user);
session.flush();
session.clear();  // close the session

//here the object is actually deleted.

Operația efectivă din baza de date va fi executată după ce metoda flush() este apelată sau tranzacția este închisă.

Ștergere în cascadă

Vă amintiți când am studiat SQL, tabelele dependente puteau fi scrise cu CONSTRAINT. Și unul dintre ei a mers așa:

CONSTRAINT ONDELETE REMOVE

Semnificația lui era că, dacă avem un tabel care conține entități copil, atunci când entitatea părinte este alocată, toți copiii săi trebuie șterși.

Să presupunem că stocăm undeva informațiile personale ale utilizatorului și setăm CONSTRAINT în baza de date, astfel încât atunci când utilizatorul este șters, aceste date să fie și ele șterse. Apoi trebuie doar să ștergem obiectul părinte și toate obiectele copil vor fi șterse la nivelul de bază:

User user = new User();
UserPrivateInfo info = new UserPrivateInfo();
user.setPrivateInfo(info);
session.persist(user);  //add the object to the database, the info object will also be saved to the database
session.flush();
session.clear();  // close the session

user = (User) session.find(User.class, user.getId() ); //receive the object from the database
session.remove(user);
session.flush();
session.clear();  // close the session

// here the user and info objects are actually removed from the database.

Eliminare de către orfan

Există, de asemenea, un alt tip de eliminare numită eliminare orfană. Este oarecum asemănător cu versiunea anterioară. O entitate copil este ștearsă atunci când relația sa cu entitatea părinte este ruptă. În acest caz, entitatea-mamă nu este de obicei ștearsă.

Să presupunem că avem un utilizator și el are o listă de postări:

User user = new User();
UserMessage message = new UserMessage();
user.getMessageList().add(message);
session.persist(user);  //add the object to the database, the message object will also be saved to the database
session.flush();
session.clear();  // close the session

user = (User) session.find(User.class, user.getId() ); //receive the object from the database
UserMessage message2 = user.getMessageList().get(0); //get the user's message
user.getMessageList().remove(message2);  //remove the message from the list
session.flush();
session.clear();  // close the session

// here the message2 object is actually removed from the database

Există, de asemenea, o nuanță importantă, dacă dorim ca Hibernate să implementeze acest comportament, acesta trebuie specificat în mod explicit atunci când se conectează două entități folosind adnotări:

@Entity
public class User {

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<UserMessage> messageList = new ArrayList<UserMessage>();

}

Ștergeți prin JPQL

Un alt mod interesant de a șterge un obiect este să scrieți o interogare HQL (sau JPQL). Doar nu uitați să apelați metoda executeUpdate() la sfârșit , altfel Hibernate creează o tranzacție numai în citire și nu veți primi nicio ștergere.

Exemplu:

User user = new User();
session.persist(user);  // add an object to the database
session.flush();
session.clear();  // close the session

session.createQuery("delete from User where id = :id")
   .setParameter("id", user.getId())
   .executeUpdate();

Schimbarea bazei de date nu va schimba în niciun fel obiectele Entity existente.

Ștergerea prin NativeQuery

În mod similar, puteți șterge și apela NativeQuery.

Exemplu:

User user = new User();
session.persist(user);  // add an object to the database
session.flush();
session.clear();  // close the session

session.createNativeQuery("DELETE FROM user WHERE id = :id")
   .setParameter("id", user.getId())
   .executeUpdate();

Modificarea în baza de date nu va afecta în niciun fel obiectele Entity existente.

Ștergere soft

Uneori, în loc să ștergeți datele din baza de date, este convenabil să le marcați pur și simplu ca șterse. Astfel de date pot participa apoi la diferite scenarii. În primul rând, o astfel de ștergere este ușor reversibilă - liniile pot fi din nou marcate ca live.

În al doilea rând, este util să „arhiviți” astfel de date de la distanță, deoarece există cazuri în care comportamentul serverului este reglementat de lege și altele asemenea. Cu toate acestea, dacă marcați datele dvs. ca șterse, atunci numai dvs. veți ști că acestea au fost șterse. Hibernate va găsi în continuare aceste date și, de asemenea, le va folosi la sortare.

Prin urmare, creatorii Hibernate au venit cu o adnotare specială cu care ar fi posibilă marcarea obiectelor ca fiind vii. Exemplu:

@Entity
@Where(clause = "DELETED = 0") //in all WHEREs "AND DELETED = 0" will be added
public class User {
	// mapping fields

	@Column(name = "DELETED") // if the value in the DELETED column == 0, then the record is alive, if 1 - dead
	private Integer deleted = 0;

	//getters and setters

    public void softDeleted() {
    	this.deleted = 1; //mark the post as dead
    }
}

Pentru a marca un obiect ca șters, trebuie doar să apelați metoda softDeleted() pe el :

User user = new User();
session.persist(user);  // add an object to the database
session.flush();
session.clear();  // close the session

user = (User) session.find(User.class, user.getId() ); //receive the object from the database
user.softDeleted(); // mark the object as deleted
session.flush();
session.clear();  // close the session

//this object will no longer reside via Hibernate