Quais são as diferenças entre os diferentes métodos de poupança em hibernação?

StackOverflow https://stackoverflow.com/questions/161224

  •  03-07-2019
  •  | 
  •  

Pergunta

O Hibernate tem um punhado de métodos que, de uma forma ou de outra, leva o seu objecto e coloca-lo no banco de dados. Quais são as diferenças entre eles, quando usar cada, e por que não há apenas um método inteligente que sabe quando usar o quê?

Os métodos que identifiquei até agora são:

  • save()
  • update()
  • saveOrUpdate()
  • saveOrUpdateCopy()
  • merge()
  • persist()
Foi útil?

Solução

Aqui está a minha compreensão dos métodos. Principalmente estes são baseados na API embora como I don 't usar tudo isso em prática.

saveOrUpdate Chamadas salvar ou atualização dependendo de alguns cheques. Por exemplo. se não existir nenhum identificador, save é chamado. Caso contrário atualização é chamado.

Salvar Persiste uma entidade. Irá atribuir um identificador se não existir. Se um faz, é essencialmente fazer uma atualização. Retorna o ID gerado da entidade.

update As tentativas de persistir a entidade usando um identificador existente. Se não existir nenhum identificador, eu acredito que uma exceção é lançada.

saveOrUpdateCopy Esta é obsoleto e não deve mais ser usado. Em vez disso, há ...

merge Agora, este é o lugar onde meu conhecimento começa a vacilar. O importante aqui é a diferença entre transitória, individual e entidades persistentes. Para mais informações sobre os estados de objeto, dar uma olhada aqui . Com Salvar e atualização, você está lidando com objetos persistentes. Eles estão ligados a uma sessão de modo Hibernate sabe o que mudou. Mas quando você tem um objeto transiente, não há sessão envolvidos. Nesses casos, você precisa usar a mala para atualizações e persistir para a poupança.

persistem Como mencionado acima, este é usado em objetos transitórios. Ela não retorna o ID gerado.

Outras dicas

╔══════════════╦═══════════════════════════════╦════════════════════════════════╗
║    METHOD    ║            TRANSIENT          ║            DETACHED            ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║       sets id if doesn't      ║   sets new id even if object   ║
║    save()    ║     exist, persists to db,    ║    already has it, persists    ║
║              ║    returns attached object    ║ to DB, returns attached object ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║       sets id on object       ║             throws             ║
║   persist()  ║     persists object to DB     ║       PersistenceException     ║
║              ║                               ║                                ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║                               ║                                ║
║   update()   ║           Exception           ║     persists and reattaches    ║
║              ║                               ║                                ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║  copy the state of object in  ║    copy the state of obj in    ║
║    merge()   ║     DB, doesn't attach it,    ║      DB, doesn't attach it,    ║
║              ║    returns attached object    ║     returns attached object    ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║                               ║                                ║
║saveOrUpdate()║           as save()           ║            as update()         ║
║              ║                               ║                                ║
╚══════════════╩═══════════════════════════════╩════════════════════════════════╝
  • Veja a Hibernate Fórum para uma explicação das diferenças sutis entre persistem e salvar. Parece que a diferença é o tempo que a instrução INSERT é finalmente executado. Desde Salvar não devolver o identificador, a instrução INSERT deve ser executada imediatamente, independentemente do estado da transação (que geralmente é uma coisa ruim). Persistir não irá executar quaisquer declarações fora da transação em execução no momento apenas para atribuir o identificador. Save / Persistir ambos trabalham no casos transitórios , ou seja, casos que não têm identificador ainda atribuídos e como tal não são salvas no DB.

  • Atualizar e Mesclar ambos trabalham no instâncias destacadas , ou seja, casos que têm uma entrada correspondente na DB, mas que são actualmente não ligado a (ou geridos por) uma sessão. A diferença entre eles é o que acontece com a instância que é passada para a função. update tentativas para reatar a instância, o que significa que pode haver nenhuma outra instância da entidade persistente ligado ao Session agora caso contrário, uma exceção é lançada. merge , no entanto, apenas copia todos os valores para uma instância persistente na Sessão (que será carregado se não está atualmente carregado). O objecto de entrada não é alterada. Então merge é mais geral do que atualização , mas podem usar mais recursos.

Este link explica em boa forma:

http://www.stevideter.com/2008/12/ 07 / saveOrUpdate-versus-merge-in-hibernate /

Todos nós temos esses problemas que nós encontramos apenas raramente o suficiente para que quando vê-los novamente, sabemos que temos resolvido isso, mas não me lembro como.

O NonUniqueObjectException lançada quando usando Session.saveOrUpdate () em Hibernate é um dos meus. Eu vou estar adicionando novas funcionalidades para uma aplicação complexa. Todos os meus testes de unidade funcionar bem. Em seguida, em testar a interface do usuário, tentando salvar um objeto, eu começar a receber uma exceção com a mensagem “um objeto diferente com o mesmo valor identificador já foi associada com a sessão.” Aqui está um código de exemplo de Java Persistence com Hibernate.

            Session session = sessionFactory1.openSession();
            Transaction tx = session.beginTransaction();
            Item item = (Item) session.get(Item.class, new Long(1234));
            tx.commit();
            session.close(); // end of first session, item is detached

            item.getId(); // The database identity is "1234"
            item.setDescription("my new description");
            Session session2 = sessionFactory.openSession();
            Transaction tx2 = session2.beginTransaction();
            Item item2 = (Item) session2.get(Item.class, new Long(1234));
            session2.update(item); // Throws NonUniqueObjectException
            tx2.commit();
            session2.close();

Para entender a causa dessa exceção, é importante compreender objetos destacados e o que acontece quando você chamar saveOrUpdate () (ou apenas update ()) em um objeto separado.

Quando fechamos uma Sessão Hibernate indivíduo, os objetos persistentes que estamos trabalhando são destacados. Isto significa que os dados ainda estão na memória da aplicação, mas Hibernate não é mais responsável para controlar alterações aos objetos.

Se, então, modificar nosso objeto destacado e quiser atualizá-lo, temos de recolocar o objeto. Durante esse processo de religação, o Hibernate irá verificar para ver se há quaisquer outras cópias do mesmo objeto. Se encontrar qualquer, tem que nos dizer que não sabe o que a cópia “real” é mais. Talvez outras mudanças foram feitas para as outras cópias que esperamos para ser salvo, mas Hibernate não sabe sobre eles, porque não foi gerenciá-los no momento.

Ao invés de salvar possivelmente dados ruins, Hibernate nos diz sobre o problema através da NonUniqueObjectException.

Então, o que devemos fazer? No Hibernate 3, temos merge () (em Hibernate 2, uso saveOrUpdateCopy ()). Este método irá forçar o Hibernate para copiar as alterações de outras instâncias destacadas para a instância que você deseja salvar, e, portanto, mescla todas as mudanças na memória antes que o save.

        Session session = sessionFactory1.openSession();
        Transaction tx = session.beginTransaction();
        Item item = (Item) session.get(Item.class, new Long(1234));
        tx.commit();
        session.close(); // end of first session, item is detached

        item.getId(); // The database identity is "1234"
        item.setDescription("my new description");
        Session session2 = sessionFactory.openSession();
        Transaction tx2 = session2.beginTransaction();
        Item item2 = (Item) session2.get(Item.class, new Long(1234));
        Item item3 = session2.merge(item); // Success!
        tx2.commit();
        session2.close();

É importante notar que se fundem retorna uma referência para a versão recém-atualizados da instância. Não é recolocar item para a sessão. Se você testar, por exemplo, a igualdade (artigo == item3), você vai encontrá-lo retorna false neste caso. Você provavelmente vai querer trabalhar com item3 a partir deste ponto em diante.

Também é importante notar que o Java Persistence API (JPA) não tem um conceito de objetos destacados e recolocado, e usa EntityManager.persist () e EntityManager.merge ().

Eu encontrei em geral que, ao usar Hibernate, saveOrUpdate () é geralmente suficiente para as minhas necessidades. Eu normalmente só precisa usar a mala quando tenho objetos que podem ter referências a objetos do mesmo tipo. Mais recentemente, a causa da exceção foi no código de validação de que a referência não foi recursiva. Eu estava carregando o mesmo objeto na minha sessão como parte da validação, causando o erro.

Onde você encontrou este problema? Fez um trabalho de mesclagem para você ou se você precisa de outra solução? Você prefere usar sempre merge, ou se preferir usá-lo somente quando necessário para casos específicos

Na verdade, a diferença entre os métodos save() e persist() Hibernate é depende da classe gerador que estamos usando.

Se a nossa classe gerador é atribuído, então não há nenhuma diferença entre) métodos save() e persist(. Porque gerador ‘atribuído’ meios, como programador, precisamos dar o valor da chave primária para salvar no direito de banco de dados [espero que você saiba este conceito geradores] Em caso de diferente classe gerador atribuído, suponho que se nosso nome classe gerador é o meio de incremento hibernate ele se auto-atribuir o valor id chave primária para a direita banco de dados [que não seja gerador atribuído apenas hibernate costumava cuidar o valor id chave primária lembrar ], portanto, neste caso, se nós chamamos save() ou método persist() seguida, ele irá inserir o registro no banco de dados normalmente Mas a coisa é ouvir, método save() pode retornar esse valor id chave primária que é gerado pelo Hibernate e podemos vê-lo por

long s = session.save(k);

Neste mesmo caso, persist() nunca dar qualquer valor para o cliente.

Eu encontrei um bom exemplo mostrando as diferenças entre todos hibernação Salvar métodos:

http: // www. journaldev.com/3481/hibernate-session-merge-vs-update-save-saveorupdate-persist-example

Em breve, de acordo com o link acima:

save ()

  • Podemos invocar este método fora de uma transação. Se usarmos isso sem transação e temos em cascata entre as entidades, em seguida, apenas a entidade primária é salvo, a menos que limpar a sessão.
  • Assim, se existem outros objetos mapeados a partir do objeto principal, que é salvo no momento de cometer transação ou quando liberar a sessão.

persist ()

  • Sua semelhante ao uso de save () na transação, por isso é seguro e cuida de todos os objetos em cascata.

saveOrUpdate ()

  • pode ser usado com ou sem a transação, e, assim como save (), se a sua utilização sem a transação, entidades mapeadas não vai ser salvo un;. Ess que liberar a sessão

  • resultados em consultas de inserção ou de atualização com base nos dados fornecidos. Se os dados estiverem presentes no banco de dados, consulta de atualização é executado.

update ()

  • atualização Hibernate deve ser usado onde sabemos que estamos apenas atualizando as informações entidade. Esta operação adiciona o objeto de entidade de contexto persistente e outras alterações são rastreadas e salvas quando transação é confirmada.
  • Assim, mesmo depois de chamar atualização, se definir quaisquer valores na entidade, que será atualizado quando submissões de transação.

merge ()

  • Hibernate merge pode ser usado para atualizar os valores existentes, no entanto, este método de criar uma cópia do objeto de entidade passou e devolvê-lo. O objeto retornado é parte do contexto persistente e monitorados para quaisquer alterações, objeto passado não é controlado. Esta é a principal diferença com merge () de todos os outros métodos.

Também para exemplos práticos de tudo isso, por favor, consulte o link que eu mencionei acima, mostra exemplos para todos esses diferentes métodos.

Esteja ciente de que se você chamar uma atualização em um objeto individual, sempre haverá uma atualização feita no banco de dados se você mudou o objeto ou não. Se não for o que você quer você deve usar Session.lock () com LockMode.NONE.

Você deve chamar update apenas se o objeto foi mudado fora do âmbito da sua sessão atual (quando em modo independente).

Como expliquei na este artigo , você deve preferir os métodos JPA maior parte do tempo, e o update para tarefas de processamento em lote.

A JPA ou entidade Hibernate pode estar em um dos quatro estados seguintes:

  • Transient (novo)
  • Dirigido (Persistente)
  • Moradia Isolada
  • Removido (suprimido)

A transição de um estado para o outro é feito através dos métodos EntityManager ou sessão.

Por exemplo, o EntityManager JPA fornece os seguintes métodos de transição de estado entidade.

enter descrição da imagem aqui

Os implementos Session Hibernate todos os métodos e EntityManager JPA fornece alguns métodos adicionais de transição de estado entidade como save, saveOrUpdate e update.

enter descrição da imagem aqui

Persistir

Para alterar o estado de uma entidade de Transient (New) para Managed (persistentes), podemos usar o método persist oferecido pelo EntityManager JPA que também é herdada pela Session Hibernate.

O método persist desencadeia uma PersistEvent que é tratado pelo DefaultPersistEventListener Hibernate ouvinte de evento.

Portanto, ao executar o seguinte caso de teste:

doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    entityManager.persist(book);

    LOGGER.info(
        "Persisting the Book entity with the id: {}", 
        book.getId()
    );
});

O Hibernate gera as instruções SQL a seguir:

CALL NEXT VALUE FOR hibernate_sequence

-- Persisting the Book entity with the id: 1

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

Observe que o id é atribuído antes de fixar a entidade Book para o contexto de persistência atual. Isso é necessário porque as entidades gerenciadas são armazenados em uma estrutura Map onde a chave é formado pelo tipo de entidade e seu identificador e o valor é a referência de entidade. Esta é a razão pela qual o EntityManager JPA eo Session Hibernate são conhecidos como o cache de primeiro nível.

Ao chamar persist, a entidade só é ligado à actualmente em execução contexto de persistência, e o INSERT pode ser adiada até que a flush é chamado.

A única exceção é a IDENTIDADE gerador que desencadeia o INSERT imediatamente uma vez que essa é a única maneira que pode obter o identificador da entidade. Por esta razão, o Hibernate não pode inserções lote para entidades usando o gerador IDENTIDADE. Para mais detalhes sobre este assunto, consulte a este artigo .

Salvar

O método save específicas do Hibernate antecede JPA e está disponível desde o início do projeto Hibernate.

O método save desencadeia uma SaveOrUpdateEvent que é tratado pelo DefaultSaveOrUpdateEventListener Hibernate ouvinte de evento. Portanto, o método save é equivalente aos métodos e update saveOrUpdate.

Para ver como o método save obras, considere o seguinte caso de teste:

doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    Session session = entityManager.unwrap(Session.class);

    Long id = (Long) session.save(book);

    LOGGER.info(
        "Saving the Book entity with the id: {}", 
        id
    );
});

Ao executar o caso de teste acima, Hibernate gera as seguintes instruções SQL:

CALL NEXT VALUE FOR hibernate_sequence

-- Saving the Book entity with the id: 1

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

Como você pode ver, o resultado é idêntico ao chamado método persist. No entanto, ao contrário persist, o método save retorna o identificador de entidade.

Para mais detalhes, veja este artigo .

Atualização

O método update específicas do Hibernate destina-se a ignorar o mecanismo de verificação suja e forçar uma atualização entidade no momento flush.

O método update desencadeia uma SaveOrUpdateEvent que é tratado pelo DefaultSaveOrUpdateEventListener Hibernate ouvinte de evento. Portanto, o método update é equivalente aos métodos e save saveOrUpdate.

Para ver como funciona o método update considere o seguinte exemplo que persiste uma entidade Book em uma transação, em seguida, ele modifica-lo, enquanto a entidade está no estado individual, e ele força o SQL UPDATE usando a chamada de método update.

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    entityManager.persist(book);

    return book;
});

LOGGER.info("Modifying the Book entity");

_book.setTitle(
    "High-Performance Java Persistence, 2nd edition"
);

doInJPA(entityManager -> {
    Session session = entityManager.unwrap(Session.class);

    session.update(_book);

    LOGGER.info("Updating the Book entity");
});

Ao executar o caso de teste acima, Hibernate gera as seguintes instruções SQL:

CALL NEXT VALUE FOR hibernate_sequence

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

-- Modifying the Book entity
-- Updating the Book entity

UPDATE 
    book 
SET 
    author = 'Vlad Mihalcea', 
    isbn = '978-9730228236', 
    title = 'High-Performance Java Persistence, 2nd edition'
WHERE 
    id = 1

Observe que o UPDATE é executado durante o Contexto nivelado Persistência, logo antes de cometer, e é por isso que a mensagem Updating the Book entity é registrado pela primeira vez.

Usando @SelectBeforeUpdate para evitar atualizações desnecessárias

Agora, a atualização é sempre vai ser executado mesmo que a entidade não foi alterada, enquanto no estado destacado. Para evitar isso, você pode usar o @SelectBeforeUpdate Hibernate anotação que irá desencadear uma declaração SELECT que loaded state buscado que é então utilizado pelo mecanismo sujo verificação.

Assim, se anotar a entidade Book com a anotação @SelectBeforeUpdate:

@Entity(name = "Book")
@Table(name = "book")
@SelectBeforeUpdate
public class Book {

    //Code omitted for brevity
}

e execute o seguinte caso de teste:

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    entityManager.persist(book);

    return book;
});

doInJPA(entityManager -> {
    Session session = entityManager.unwrap(Session.class);

    session.update(_book);
});

Hibernate executa as instruções SQL a seguir:

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

SELECT 
    b.id,
    b.author AS author2_0_,
    b.isbn AS isbn3_0_,
    b.title AS title4_0_
FROM 
    book b
WHERE 
    b.id = 1

Observe que, desta vez, não há UPDATE executado desde o mecanismo de verificação suja Hibernate detectou que a entidade não foi modificado.

saveOrUpdate

O método saveOrUpdate específicas do Hibernate é apenas um alias para save e update.

O método saveOrUpdate desencadeia uma SaveOrUpdateEvent que é tratado pelo DefaultSaveOrUpdateEventListener Hibernate ouvinte de evento. Portanto, o método update é equivalente aos métodos e save saveOrUpdate.

Agora, você pode usar saveOrUpdate quando você quer persistir uma entidade ou para forçar uma UPDATE como ilustrado pelo exemplo a seguir.

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    Session session = entityManager.unwrap(Session.class);
    session.saveOrUpdate(book);

    return book;
});

_book.setTitle("High-Performance Java Persistence, 2nd edition");

doInJPA(entityManager -> {
    Session session = entityManager.unwrap(Session.class);
    session.saveOrUpdate(_book);
});

Cuidado com o NonUniqueObjectException

Um problema que pode ocorrer com save, update e saveOrUpdate é se o contexto de persistência já contém uma referência de entidade com o mesmo id e do mesmo tipo, como no exemplo a seguir:

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    Session session = entityManager.unwrap(Session.class);
    session.saveOrUpdate(book);

    return book;
});

_book.setTitle(
    "High-Performance Java Persistence, 2nd edition"
);

try {
    doInJPA(entityManager -> {
        Book book = entityManager.find(
            Book.class, 
            _book.getId()
        );

        Session session = entityManager.unwrap(Session.class);
        session.saveOrUpdate(_book);
    });
} catch (NonUniqueObjectException e) {
    LOGGER.error(
        "The Persistence Context cannot hold " +
        "two representations of the same entity", 
        e
    );
}

Agora, ao executar o caso de teste acima, Hibernate vai lançar um NonUniqueObjectException porque a segunda EntityManager já contém uma entidade Book com o mesmo identificador como o que passar para update, e o contexto de persistência não pode realizar duas representações do mesma entidade.

org.hibernate.NonUniqueObjectException: 
    A different object with the same identifier value was already associated with the session : [com.vladmihalcea.book.hpjp.hibernate.pc.Book#1]
    at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:651)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:227)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:92)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:682)
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:674)

Merge

Para evitar o NonUniqueObjectException, você precisa usar o método merge oferecido pelo EntityManager JPA e herdado pelo Session Hibernate também.

Como explicado na este artigo , o merge busca um novo instantâneo entidade de a base de dados, se não há nenhuma referência entidade encontrada no contexto de persistência, e copia o estado da entidade independente passado para o merge método.

O método merge desencadeia uma MergeEvent que é tratado pelo DefaultMergeEventListener Hibernate ouvinte de evento.

Para ver como funciona o método merge considere o seguinte exemplo que persiste uma entidade Book em uma transação, em seguida, ele modifica-lo, enquanto a entidade está no estado individual, e passar a entidade destacada para merge em uma subsequência Persistência Contexto.

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    entityManager.persist(book);

    return book;
});

LOGGER.info("Modifying the Book entity");

_book.setTitle(
    "High-Performance Java Persistence, 2nd edition"
);

doInJPA(entityManager -> {
    Book book = entityManager.merge(_book);

    LOGGER.info("Merging the Book entity");

    assertFalse(book == _book);
});

Ao executar o caso de teste acima, Hibernate executadas as seguintes instruções SQL:

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

-- Modifying the Book entity

SELECT 
    b.id,
    b.author AS author2_0_,
    b.isbn AS isbn3_0_,
    b.title AS title4_0_
FROM 
    book b
WHERE 
    b.id = 1

-- Merging the Book entity

UPDATE 
    book 
SET 
    author = 'Vlad Mihalcea', 
    isbn = '978-9730228236', 
    title = 'High-Performance Java Persistence, 2nd edition'
WHERE 
    id = 1

Observe que o referência de entidade retornada por merge é diferente do destacada passamos ao método merge.

Agora, embora você deve preferir usar JPA merge ao copiar o estado entidade individual, o SELECT extra pode ser problemático quando executar uma tarefa de processamento em lote.

Por esta razão, você deve preferir usar update quando tiver certeza de que não há nenhuma referência a entidade já anexado ao actualmente em execução contexto de persistência e que a entidade destacada foi modificado.

Para mais detalhes sobre este tópico, veja este artigo .

Conclusão

Para persistir uma entidade, você deve usar o método JPA persist. Para copiar o estado entidade individual, merge deve ser preferido. O método é útil para update apenas as tarefas de processamento em lote. O save e saveOrUpdate são apenas aliases para update e você não deve provavelmente usá-los em tudo.

Alguns desenvolvedores chamam save mesmo quando a entidade já é gerido, mas isso é um erro e desencadeia um evento redundante, pois, por entidades gerenciadas, a atualização é manipulada no momento contexto nivelado Persistência.

Para mais detalhes, consulte a este artigo .

Nenhum dos seguintes respostas estão certas. Todos estes métodos só parecem ser iguais, mas na prática fazer coisas absolutamente diferentes. É difícil fazer comentários curtos. Melhor dar um link para a documentação completa sobre esses métodos: http://docs.jboss.org/hibernate /core/3.6/reference/en-US/html/objectstate.html

Nenhuma das respostas acima estão completas. Embora resposta Leo Theobald aparência mais próxima resposta.

O ponto básico é como hibernação é lidar com estados de entidades e como ele lida com eles quando há uma mudança de estado. Tudo deve ser visto com respeito às ondas e commits, assim, que toda a gente parece ter ignorado completamente.

Nunca use o método Save do Hibernate. Esquecer que ainda existe no Hibernate!

Persistir

Como todos explicou, Persistir basicamente transições uma entidade de estado "transitória" para Estado "geridos". Neste ponto, a lama ou um commit pode criar uma instrução de inserção. Mas a entidade vai ainda permanece no estado "geridos". isso não muda com flush.

Neste ponto, se você "Persistir" novamente haverá nenhuma mudança. E não haverá mais nenhuma salva se tentarmos persistir uma entidade persistente.

A diversão começa quando tentamos expulsar a entidade.

Um evict é uma função especial do Hibernate que fará a transição a entidade de "Managed" para "isolada". Nós não podemos chamar a persistir em uma entidade separada. Se fizermos isso, então Hibernate gera uma transação de exceção e toda fica revertida em cometer.

Merge vs Atualização

Estes são 2 funções interessantes fazendo coisas diferentes quando tratados de maneiras diferentes. Ambos estão tentando fazer a transição da entidade de estado "isolada" para o estado "geridos". Mas fazê-lo de forma diferente.

Entenda um fato que meios Isolada tipo de um estado "offline". e meios gerenciados "Online" estado.

Observe o código abaixo:

Session ses1 = sessionFactory.openSession();

    Transaction tx1 = ses1.beginTransaction();

    HibEntity entity = getHibEntity();

    ses1.persist(entity);
    ses1.evict(entity);

    ses1.merge(entity);

    ses1.delete(entity);

    tx1.commit();

Quando você fazer isso? O que você acha que acontecerá? Se você disse que isso irá aumentar exceção, então você está correto. Isto irá aumentar exceção porque, merge já trabalhou em entidade objeto, que é separada do Estado. Mas não alterar o estado do objeto.

Por trás da cena, merge vai levantar uma consulta seleção e, basicamente, retorna uma cópia da entidade que está em estado ligado. Observe o código abaixo:

Session ses1 = sessionFactory.openSession();

    Transaction tx1 = ses1.beginTransaction();
    HibEntity entity = getHibEntity();

    ses1.persist(entity);
    ses1.evict(entity);

    HibEntity copied = (HibEntity)ses1.merge(entity);
    ses1.delete(copied);

    tx1.commit();

O exemplo acima funciona porque merge trouxe uma nova entidade no contexto que está em estado persistido.

Quando aplicado com atualizar o mesmo funciona bem porque a atualização não realmente trazer uma cópia da entidade como merge.

Session ses1 = sessionFactory.openSession();

    Transaction tx1 = ses1.beginTransaction();

    HibEntity entity = getHibEntity();

    ses1.persist(entity);
    ses1.evict(entity);

    ses1.update(entity);

    ses1.delete(entity);

    tx1.commit();

Ao mesmo tempo em rastreamento de depuração, podemos ver que Update não tem levantado consulta SQL de escolha como merge.

excluir

No exemplo acima, eu usei de exclusão sem falar de exclusão. Excluir, basicamente, a transição da entidade de estado conseguiu estado "removido". E quando toda velocidade ou comprometidos irá emitir um comando de exclusão para loja.

No entanto, é possível trazer a volta entidade para Estado "administrado" de estado "removido" usando o método persistir.

Hope a explicação acima esclareceu todas as dúvidas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top