Usuwanie za pomocą metody remove().

Na koniec przyjrzyjmy się usuwaniu obiektu. W zasadzie usuwanie obiektów z bazy danych jest bardzo proste, ale jak to mówią, są niuanse. I jest sześć takich niuansów:

  • Usuwanie za pomocą metody remove().
  • Przeprowadzka dla firmy
  • Usunięcie przez sierotę
  • Usuń za pomocą JPQL
  • Usuwanie przez NativeQuery
  • softDeleted()

Zaczniemy od najbardziej oczywistego rozwiązania – wywołania metody 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.

Właściwa operacja w bazie danych zostanie wykonana po wywołaniu metody flush() lub zamknięciu transakcji.

Usuwanie kaskadowe

Czy pamiętasz, kiedy studiowaliśmy SQL, tabele zależne można było pisać za pomocą CONSTRAINT. A jeden z nich szedł tak:

CONSTRAINT ONDELETE REMOVE

Jego znaczenie polegało na tym, że jeśli mamy tabelę zawierającą jednostki podrzędne, to po przydzieleniu jednostki nadrzędnej wszystkie jej elementy podrzędne muszą zostać usunięte.

Załóżmy, że przechowujemy gdzieś dane osobowe użytkownika i ustawiamy CONSTRAINT w bazie danych, aby po usunięciu użytkownika te dane również zostały usunięte. Następnie wystarczy usunąć obiekt nadrzędny, a wszystkie obiekty podrzędne zostaną usunięte na poziomie podstawowym:

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.

Usunięcie przez sierotę

Istnieje również inny rodzaj usuwania zwany usuwaniem sierot. Jest trochę podobny do poprzedniej wersji. Jednostka podrzędna jest usuwana, gdy jej relacja z jednostką nadrzędną zostaje zerwana. W takim przypadku jednostka nadrzędna zwykle nie jest usuwana.

Powiedzmy, że mamy użytkownika, który ma listę postów:

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

Istnieje również ważny niuans, jeśli chcemy, aby Hibernate zaimplementował to zachowanie, musi to być wyraźnie określone podczas łączenia dwóch podmiotów za pomocą adnotacji:

@Entity
public class User {

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

}

Usuń przez JPQL

Innym ciekawym sposobem usunięcia obiektu jest napisanie zapytania HQL (lub JPQL). Tylko nie zapomnij wywołać metody executeUpdate() na końcu , w przeciwnym razie Hibernate utworzy transakcję tylko do odczytu i nie otrzymasz żadnego usunięcia.

Przykład:

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();

Zmiana bazy danych nie zmieni w żaden sposób istniejących obiektów Entity.

Usuwanie przez NativeQuery

Podobnie możesz usuwać i wywoływać NativeQuery.

Przykład:

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();

Zmiana w bazie danych nie wpłynie w żaden sposób na istniejące obiekty Entity.

Miękkie usuwanie

Czasami zamiast usuwać dane w bazie danych, wygodnie jest po prostu oznaczyć je jako usunięte. Takie dane mogą następnie uczestniczyć w różnych scenariuszach. Po pierwsze, takie usunięcie jest łatwo odwracalne - linie można ponownie oznaczyć jako żywe.

Po drugie, warto „archiwizować” takie zdalne dane, ponieważ zdarzają się przypadki, gdy zachowanie serwera jest regulowane przez prawo itp. Jeśli jednak oznaczysz swoje dane jako usunięte, tylko Ty będziesz wiedział, że zostały usunięte. Hibernate nadal znajdzie te dane i użyje ich podczas sortowania.

Dlatego twórcy Hibernate wymyślili specjalną adnotację, za pomocą której można by oznaczać obiekty jako żywe. Przykład:

@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
    }
}

Aby oznaczyć obiekt jako usunięty, wystarczy wywołać na nim metodę softDeleted() :

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