As nuances do método merge()

Se você quiser usar o Hibernate para alterar um objeto que já foi armazenado no banco de dados, também existem vários métodos para isso.

O primeiro é o método merge() , que atualiza as informações no banco de dados com base no objeto passado . Isso invocará a consulta SQL UPDATE. Exemplo:

User user = new User();
user.setName("Kolyan");
session.save(user);

session.evict(user);     // detach the object from the session
user.setName("Masha");

User user2 = (User) session.merge(user);

Existem várias nuances importantes aqui.

Primeiro, o método merge() retorna o resultado, o objeto atualizado. Este objeto tem um estado Persist e está anexado ao objeto de sessão. O objeto passado para o método merge() não muda.

Pode parecer que não há diferença entre user e user2, mas não é. Você pode passar um objeto POJO para o método merge() e, como resultado, o método pode retornar um proxy (dependendo das configurações do Hibernate). Portanto, lembre-se de que o método merge() não altera o objeto passado.

Em segundo lugar, se o objeto passado para merge() tiver o status Transient (e não tiver um ID), uma linha separada será criada para ele no banco de dados. Em outras palavras, o comando persist() será executado .

Em terceiro lugar, se um objeto já anexado à sessão (com o status Persist) for passado para o método merge() , nada acontecerá - o método simplesmente retornará o mesmo objeto. Por que? E tudo porque quando a transação for confirmada, os dados serão gravados no banco de dados de qualquer maneira:

User user = new User();
user.setName("Kolyan");
session.save(user);

user.setName("Masha"); //change the object attached to the session

session.close();  //all changed objects will be written to the database

Não há necessidade de salvar o objeto toda vez após qualquer uma de suas alterações. Se este objeto estiver no status Persist, o Hibernate fará tudo sozinho. Se você alterar um objeto que está “anexado à base”, todas as suas alterações serão gravadas na base.

As nuances do método update()

O Hibernate também possui um método update() , que, como o método save() , foi herdado de versões anteriores. Com este método, você só pode atualizar os dados de um objeto já salvo. Isso invocará a consulta SQL UPDATE. Exemplo:

User user = new User();
user.setName("Kolyan");
session.save(user);

session.evict(user);     // detach the object from the session
user.setName("Masha");

session.update(user);

Este método não retorna nada e não altera o objeto existente.

Se você chamar esse método em um novo objeto, uma exceção simplesmente será lançada:

User user = new User();
user.setName("Kolyan");
session.update(user);   //an exception will be thrown here

Método saveOrUpdate()

Antes do advento do JPA, a função do método persist() era executada pelo método saveOrUpdate() . Sua tarefa era atualizar as informações sobre o objeto existente no banco de dados e, se não houver, criá-lo. Quase sempre é usado no lugar dos métodos save() e update() .

Ao contrário do método update() , ele pode alterar o objeto passado para ele. Por exemplo, defina-o para o ID que foi atribuído ao salvar no banco de dados. Exemplo:

User user = new User();
user.setName("Kolyan");
session.saveOrUpdate(user);   //object will be written to the database

Como funciona:

  • se o objeto passado tiver um ID, o método UPDATE SQL é chamado
  • se o ID do objeto passado não for definido, o método INSERT SQL será chamado