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(„Kolan”);
session.persist(user); // dodaj obiekt do bazy danych
session.flush();
session.clear(); // zamknij sesję
user = (User) session.find(User.class, user.getId() ); //odbierz obiekt z bazy danych
session.remove(user);
session.flush();
session.clear(); // zamknij sesję
//tutaj obiekt jest faktycznie usuwany.
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); //dodaj obiekt do bazy danych, obiekt info również zostanie zapisany w bazie danych
session.flush();
session.clear(); // zamknij sesję
user = (User) session.find(User.class, user.getId() ); //odbierz obiekt z bazy danych
session.remove(user);
session.flush();
session.clear(); // zamknij sesję
// tutaj obiekty user i info są faktycznie usuwane z bazy danych.
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); //dodaj obiekt do bazy danych, obiekt wiadomości również zostanie zapisany w bazie danych
session.flush();
session.clear(); // zamknij sesję
user = (User) session.find(User.class, user.getId() ); //odbierz obiekt z bazy danych
UserMessage message2 = user.getMessageList().get(0); //pobierz wiadomość użytkownika
user.getMessageList().remove(message2); //usuń wiadomość z listy
session.flush();
session.clear(); // zamknij sesję
// tutaj obiekt message2 jest faktycznie usuwany z bazy danych
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); // dodaj obiekt do bazy danych
session.flush();
session.clear(); // zamknij sesję
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); // dodaj obiekt do bazy danych
session.flush();
session.clear(); // zamknij sesję
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") //we wszystkich miejscach WHERE zostanie dodane „AND DELETED = 0”.
public class User {
// mapowanie pól
@Column(name = "DELETED") // jeśli wartość w kolumnie DELETED == 0, to rekord jest żywy, jeśli 1 - martwy
private Integer deleted = 0;
// pobierające i ustawiające
public void softDeleted() {
this.deleted = 1; //oznacz post jako martwy
}
}
Aby oznaczyć obiekt jako usunięty, wystarczy wywołać na nim metodę softDeleted() :
User user = new User();
session.persist(user); // dodaj obiekt do bazy danych
session.flush();
session.clear(); // zamknij sesję
user = (User) session.find(User.class, user.getId() ); //odbierz obiekt z bazy danych
user.softDeleted(); // zaznacz obiekt jako usunięty
session.flush();
session.clear(); // zamknij sesję
//ten obiekt nie będzie już rezydował w Hibernacji
GO TO FULL VERSION