Qual é a diferença entre persist () e merge () em JPA e Hibernate?

119

Qual é a diferença entre persist () e merge () no Hibernate?

persist() pode criar uma consulta UPDATE & INSERT, por exemplo:

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();

neste caso, a consulta será gerada assim:

Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?

portanto, o persist()método pode gerar uma inserção e uma atualização.

Agora com merge():

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

Isso é o que vejo no banco de dados:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Madonna
3           Elvis Presley
4           Luciano Pavarotti

Agora atualize um registro usando merge()

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setId(2);
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

Isso é o que vejo no banco de dados:

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley
Jimit Tank
fonte
7
O javadoc é muito explícito sobre o que eles fazem e quais são as diferenças. Você leu e entendeu?
Skaffman
1
Verifique stackoverflow.com/questions/161224/…
Jigar Joshi

Respostas:

144

A especificação JPA contém uma descrição muito precisa da semântica dessas operações, melhor do que no javadoc:

A semântica da operação persist , aplicada a uma entidade X é a seguinte:

  • Se X for uma nova entidade, ela será gerenciada. A entidade X será inserida no banco de dados durante ou antes da confirmação da transação ou como resultado da operação de liberação.

  • Se X for uma entidade gerenciada preexistente, ela será ignorada pela operação persist. No entanto, a operação persist é cascateada para entidades referenciadas por X, se os relacionamentos de X para essas outras entidades forem anotados com o valor do elemento de anotação cascade=PERSISTou cascade=ALLou especificados com o elemento descritor XML equivalente.

  • Se X for uma entidade removida, ela se tornará gerenciada.

  • Se X for um objeto desanexado, o EntityExistsExceptionpode ser lançado quando a operação persist for invocada, ou o EntityExistsExceptionou outro PersistenceExceptionpode ser lançado no momento da liberação ou confirmação.

  • Para todas as entidades Y referenciadas por um relacionamento de X, se o relacionamento com Y tiver sido anotado com o valor do elemento cascade cascade=PERSISTou cascade=ALL, a operação persist será aplicada a Y.


A semântica do operação de mesclagem aplicada a uma entidade X é a seguinte:

  • Se X for uma entidade separada, o estado de X será copiado em uma instância de entidade gerenciada pré-existente X 'da mesma identidade ou uma nova cópia gerenciada X' de X será criada.

  • Se X for uma nova instância de entidade, uma nova instância de entidade gerenciada X 'é criada e o estado de X é copiado para a nova instância de entidade gerenciada X'.

  • Se X for uma instância de entidade removida, um IllegalArgumentExceptionserá lançado pela operação de mesclagem (ou a confirmação da transação falhará).

  • Se X for uma entidade gerenciada, ela será ignorada pela operação de mesclagem, no entanto, a operação de mesclagem será enviada em cascata para entidades referenciadas por relacionamentos de X se esses relacionamentos tiverem sido anotados com o valor do elemento em cascata cascade=MERGEou cascade=ALLanotação.

  • Para todas as entidades Y referenciadas por relacionamentos de X com o valor do elemento em cascata cascade=MERGEou cascade=ALL, Y é mesclado recursivamente como Y '. Para todos os Y referenciados por X, X 'é definido como referência Y'. (Observe que se X for gerenciado, então X é o mesmo objeto que X '.)

  • Se X for uma entidade fundida com X ', com uma referência a outra entidade Y, onde cascade=MERGEou cascade=ALLnão é especificado, a navegação da mesma associação de X' produz uma referência a um objeto gerenciado Y 'com a mesma identidade persistente de Y.

axtavt
fonte
Obrigado pela informação. Eu vejo a semântica de ambas as definições. Mas a questão é sobre as diferenças entre eles. Talvez apresente a lista de estados e 2 subseções para cada comportamento diferente de persistvs merge?
AlikElzin-kilaka
25

Isso está vindo JPA. De uma forma muito simples:

  • persist(entity) deve ser usado com entidades totalmente novas, para adicioná-las ao BD (se a entidade já existe no BD haverá lançamento de EntityExistsException).

  • merge(entity) deve ser usado para colocar a entidade de volta no contexto de persistência se a entidade foi desanexada e foi alterada.

Krystian
fonte
você pode adicionar uma fonte à sua explicação? Obrigado.
AlikElzin-kilaka
@ AlikElzin-kilaka tal explicação, pelo que me lembro, encontrei em um livro "Beginning Java EE 7".
Krystian,
12

Persist deve ser chamado apenas em novas entidades, enquanto merge serve para reconectar entidades desanexadas.

Se você estiver usando o gerador atribuído, usar merge em vez de persist pode causar uma instrução SQL redundante , afetando o desempenho.

Além disso, chamar merge para entidades gerenciadas também é um erro, pois as entidades gerenciadas são gerenciadas automaticamente pelo Hibernate e seu estado é sincronizado com o registro do banco de dados pelo mecanismo de verificação suja ao liberar o Contexto de Persistência .

Vlad Mihalcea
fonte
1

A diferença mais importante é esta:

  • No caso de persistmétodo, se a entidade a ser gerenciada no contexto de persistência já existe no contexto de persistência, a nova é ignorada. (Nada aconteceu)

  • Mas no caso do mergemétodo, a entidade que já é gerenciada no contexto de persistência será substituída pela nova entidade (atualizada) e uma cópia desta entidade atualizada retornará. (de agora em diante, todas as alterações devem ser feitas nesta entidade retornada se você quiser refletir suas alterações no contexto de persistência)

Od Chan
fonte