Removing with the remove() Method

Finally, let's look at deleting an object. In principle, deleting objects from the database is very simple, but as they say, there are nuances. And there are six such nuances:

  • Removing with the remove() Method
  • Removal for the company
  • Removal by Orphan
  • Delete with JPQL
  • Deletion via NativeQuery
  • softDeleted()

And we'll start with the most obvious solution - calling the remove() method .

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.

The actual operation in the database will be executed after the flush() method is called or the transaction is closed.

Cascading delete

Do you remember when we studied SQL, dependent tables could be written with CONSTRAINT. And one of them went like this:

CONSTRAINT ONDELETE REMOVE

Its meaning was that if we have a table that contains child entities, then when the parent entity is allocated, all its children must be deleted.

Suppose we store the user's personal information somewhere and set up CONSTRAINT in the database so that when the user is deleted, this data is also deleted. Then we just need to delete the parent object and all child objects will be deleted at the base level:

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.

Removal by Orphan

There is also another type of removal called Orphan removal. It is somewhat similar to the previous version. A child entity is deleted when its relationship with the parent entity is broken. In this case, the parent entity is usually not deleted.

Let's say we have a user and he has a list of posts:

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

There is also an important nuance, if we want Hibernate to implement this behavior, it must be explicitly specified when linking two entities using annotations:

@Entity
public class User {

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

}

Delete via JPQL

Another interesting way to delete an object is to write an HQL (or JPQL) query. Just don't forget to call the executeUpdate() method at the end , otherwise Hibernate creates a read-only transaction and you won't get any deletion.

Example:

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

Changing the database will not change existing Entity objects in any way.

Deletion via NativeQuery

Similarly, you can delete and call NativeQuery.

Example:

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

The change in the database will not affect existing Entity objects in any way.

Soft delete

Sometimes, instead of deleting data in the database, it is convenient to simply mark it as deleted. Such data can then participate in various scenarios. Firstly, such a deletion is easily reversible - the lines can again be marked as live.

Secondly, it is useful to “archive” such remote data, because there are cases when the behavior of the server is regulated by law and the like. However, if you mark your data as deleted, then only you will know that it has been deleted. Hibernate will still find this data and also use it when sorting.

Therefore, the creators of Hibernate came up with a special annotation with which it would be possible to mark objects as alive. Example:

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

To mark an object as deleted, you just need to call the softDeleted() method on it :

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
undefined
1
Task
Module 4. Working with databases, level 11, lesson 4
Locked
task1104
task1104
undefined
1
Task
Module 4. Working with databases, level 11, lesson 4
Locked
task1105
task1105