Ta bort med metoden remove()

Låt oss slutligen titta på att ta bort ett objekt. I princip är det väldigt enkelt att ta bort objekt från databasen, men som de säger, det finns nyanser. Och det finns sex sådana nyanser:

  • Ta bort med metoden remove()
  • Borttagning för företaget
  • Borttagning av Orphan
  • Ta bort med JPQL
  • Radering via NativeQuery
  • softDeleted()

Och vi börjar med den mest uppenbara lösningen - att anropa metoden 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.

Den faktiska operationen i databasen kommer att exekveras efter att flush() -metoden anropats eller transaktionen stängts.

Kaskadradering

Kommer du ihåg när vi studerade SQL kunde beroende tabeller skrivas med CONSTRAINT. Och en av dem gick så här:

CONSTRAINT ONDELETE REMOVE

Dess innebörd var att om vi har en tabell som innehåller underordnade enheter måste alla dess underordnade enheter tas bort när den överordnade enheten tilldelas.

Anta att vi lagrar användarens personliga information någonstans och ställer in CONSTRAINT i databasen så att när användaren raderas så raderas även denna data. Sedan behöver vi bara ta bort det överordnade objektet och alla underordnade objekt kommer att raderas på basnivån:

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.

Borttagning av Orphan

Det finns också en annan typ av borttagning som kallas Orphan removal. Den är lite lik den tidigare versionen. En underordnad enhet tas bort när dess relation till den överordnade enheten bryts. I det här fallet tas den överordnade enheten vanligtvis inte bort.

Låt oss säga att vi har en användare och han har en lista med inlägg:

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

Det finns också en viktig nyans, om vi vill att Hibernate ska implementera detta beteende måste det uttryckligen anges när två enheter länkas med annoteringar:

@Entity
public class User {

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

}

Ta bort via JPQL

Ett annat intressant sätt att ta bort ett objekt är att skriva en HQL (eller JPQL) fråga. Glöm bara inte att anropa metoden executeUpdate() i slutet , annars skapar Hibernate en skrivskyddad transaktion och du kommer inte få någon radering.

Exempel:

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

Att ändra databasen kommer inte att ändra befintliga Entity-objekt på något sätt.

Radering via NativeQuery

På samma sätt kan du ta bort och anropa NativeQuery.

Exempel:

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

Ändringen i databasen kommer inte att påverka befintliga Entity-objekt på något sätt.

Mjuk borttagning

Ibland, istället för att radera data i databasen, är det bekvämt att helt enkelt markera det som raderat. Sådan data kan sedan delta i olika scenarier. För det första är en sådan radering lätt reversibel - linjerna kan återigen markeras som live.

För det andra är det användbart att "arkivera" sådan fjärrdata, eftersom det finns fall då serverns beteende regleras av lag och liknande. Men om du markerar din data som raderad är det bara du som vet att den har raderats. Hibernate kommer fortfarande att hitta denna data och även använda den vid sortering.

Därför kom skaparna av Hibernate med en speciell anteckning med vilken det skulle vara möjligt att markera objekt som levande. Exempel:

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

För att markera ett objekt som borttaget behöver du bara anropa metoden softDeleted() på det :

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