Removendo com o método remove()

Por fim, vamos examinar a exclusão de um objeto. Em princípio, deletar objetos do banco de dados é muito simples, mas como dizem, existem nuances. E existem seis dessas nuances:

  • Removendo com o método remove()
  • Remoção para empresa
  • Remoção por Órfão
  • Excluir com JPQL
  • Exclusão via NativeQuery
  • softDeleted()

E começaremos com a solução mais óbvia - chamar o método 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.

A operação real no banco de dados será executada depois que o método flush() for chamado ou a transação for fechada.

Excluir em cascata

Você se lembra quando estudamos SQL, tabelas dependentes podem ser escritas com CONSTRAINT. E um deles foi assim:

CONSTRAINT ONDELETE REMOVE

Seu significado era que, se tivéssemos uma tabela que contivesse entidades filhas, quando a entidade pai fosse alocada, todos os seus filhos deveriam ser excluídos.

Suponha que armazenemos as informações pessoais do usuário em algum lugar e configuremos CONSTRAINT no banco de dados para que, quando o usuário for excluído, esses dados também sejam excluídos. Então, só precisamos excluir o objeto pai e todos os objetos filhos serão excluídos no nível base:

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.

Remoção por Órfão

Há também outro tipo de remoção chamado remoção órfã. É um pouco semelhante à versão anterior. Uma entidade filha é excluída quando seu relacionamento com a entidade pai é interrompido. Nesse caso, a entidade pai geralmente não é excluída.

Digamos que temos um usuário e ele tem uma lista de postagens:

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

Há também uma nuance importante, se quisermos que o Hibernate implemente esse comportamento, ele deve ser especificado explicitamente ao vincular duas entidades usando anotações:

@Entity
public class User {

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

}

Excluir via JPQL

Outra maneira interessante de excluir um objeto é escrever uma consulta HQL (ou JPQL). Apenas não se esqueça de chamar o método executeUpdate() no final , caso contrário, o Hibernate criará uma transação somente leitura e você não obterá nenhuma exclusão.

Exemplo:

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

Alterar o banco de dados não alterará os objetos Entity existentes de forma alguma.

Exclusão via NativeQuery

Da mesma forma, você pode excluir e chamar NativeQuery.

Exemplo:

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

A alteração no banco de dados não afetará os objetos Entity existentes de forma alguma.

Exclusão reversível

Às vezes, em vez de excluir os dados do banco de dados, é conveniente simplesmente marcá-los como excluídos. Esses dados podem então participar de vários cenários. Em primeiro lugar, essa exclusão é facilmente reversível - as linhas podem ser novamente marcadas como ativas.

Em segundo lugar, é útil “arquivar” esses dados remotos, porque há casos em que o comportamento do servidor é regulamentado por lei e similares. No entanto, se você marcar seus dados como excluídos, somente você saberá que eles foram excluídos. O Hibernate ainda encontrará esses dados e também os usará ao classificar.

Portanto, os criadores do Hibernate criaram uma anotação especial com a qual seria possível marcar objetos como vivos. Exemplo:

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

Para marcar um objeto como excluído, você só precisa chamar o método softDeleted() nele :

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