Hibernate: guardar, manter, atualizar, em série, saveOrUpdate

Introdução

neste artigo vamos discutir as diferenças entre os vários métodos da interface Session: guardar, manter, atualizar, em série, saveOrUpdate.

esta não é uma introdução ao hibernar e você já deve saber os fundamentos da configuração, Mapeamento Objeto-Relacional e trabalhar com instâncias de entidades. Para um artigo introdutório para hibernar, visite o nosso tutorial sobre Hibernate 4 com a Primavera.

:

apagar objectos com hibernado

guia rápido para apagar uma entidade em hibernado.Leia mais →

procedimentos armazenados com hibernado

este artigo discute em breve como chamar os procedimentos de armazenamento de hibernado.Leia mais →

An Overview of Identifiers in Hibernate / JPA

Learn how to map entity identifiers with Hibernate.Leia mais →

Session as a Persistence Context Implementation

The Session interface has several methods that eventually result in saving data to the database: persist, save, update, merge, saveOrUpdate. Para compreender a diferença entre estes métodos, devemos primeiro discutir o propósito da sessão como um contexto de persistência e a diferença entre os estados de instâncias de entidade em relação à sessão.

devemos também compreender a história do desenvolvimento hibernado que levou a alguns métodos de API parcialmente duplicados.

2.1. Instâncias da entidade gerenciadora

aparte do mapeamento objeto-relacional em si, um dos problemas que Hibernate tinha a intenção de resolver é o problema das entidades gerentes durante o tempo de execução. A noção de” contexto de persistência ” é a solução de Hibernate para este problema. O contexto de persistência pode ser pensado como um container ou um cache de primeiro nível para todos os objetos que você carregou ou salvou em um banco de dados durante uma sessão.

a sessão é uma transação lógica, que os limites são definidos pela lógica de negócios da sua aplicação. Quando você trabalha com o banco de dados através de um contexto de persistência, e todas as instâncias de sua entidade estão anexadas a este contexto, você deve sempre ter uma única instância de entidade para cada registro de banco de dados que você interagiu durante a sessão com.

em hibernado, o contexto de persistência é representado por org.Hibernar.Instância de sessão. Para a App, é o javax.persistência.EntityManager. Quando usamos hibernar como um provedor de JPA e operamos através de interface EntityManager, a implementação desta interface basicamente envolve o objeto de sessão subjacente. No entanto, sessão Hibernada fornece uma interface mais rica com mais possibilidades, então às vezes é útil trabalhar com sessão diretamente.

2.2. Estados das Instâncias de Entidade

Qualquer instância da entidade em seu aplicativo aparece em um dos três principais estados em relação à persistência de Sessão contexto:

  • transiente — este exemplo não é, e nunca foi, anexado a uma Sessão; esta instância não tem linhas correspondentes no banco de dados; é apenas um novo objeto que você criou para salvar o banco de dados;
  • persistente — essa instância está associada a um único objeto de Sessão; após a liberação da Sessão para a base de dados, esta entidade é garantido para ter um correspondente consistente registro no banco de dados;
  • detached — esta instância foi uma vez conectado a uma Sessão (no estado persistente), mas agora não; uma instância entra nesse estado se retira-lo do contexto, claro ou fechar a Sessão, ou colocar a instância através de serialização/desserialização processo.

aqui está um diagrama de Estado simplificado com comentários sobre métodos de sessão que fazem as transições de Estado acontecer.

2016-07-11_13-38-11

quando a instância da entidade estiver no estado persistente, todas as alterações que fizer aos campos mapeados desta instância serão aplicadas aos registos e campos correspondentes da base de dados ao limpar a sessão. A instância persistente pode ser considerada como “online”, enquanto a instância destacada ficou” offline ” e não é monitorada para mudanças.

Isto significa que quando você alterar campos de um objeto persistente, você não tem que chamar salvar, atualizar ou qualquer um desses métodos para obter essas alterações para o banco de dados: tudo o que você precisa é para confirmar a transação, ou flush, ou fechar a sessão, quando você é feito com ele.

2.3. Conformity to JPA Specification

Hibernate was the most successful Java ORM implementation. Não admira que a especificação para a API persistência Java (JPA) tenha sido fortemente influenciada pela API Hibernada. Infelizmente, houve também muitas diferenças: algumas grandes, Outras mais subtis.

para agir como uma implementação da norma DA APP, a APIs Hibernada teve de ser revista. Vários métodos foram adicionados à interface de sessão para combinar com a interface EntityManager. Estes métodos servem ao mesmo propósito que os métodos “originais”, mas estão em conformidade com a especificação e, portanto, têm algumas diferenças.

diferenças entre as operações

é importante entender desde o início que todos os métodos (persistir, gravar, atualizar, mesclar, saveOrUpdate) não resultam imediatamente na atualização SQL correspondente ou inserir declarações. A gravação real de dados para a base de dados ocorre ao cometer a transação ou ao limpar a sessão.

os métodos mencionados basicamente gerem o estado das instâncias da entidade através da transição entre diferentes estados ao longo do ciclo de vida.

como uma entidade de exemplo, vamos usar uma pessoa de entidade mapeada com anotações simples:

@Entitypublic class Person { @Id @GeneratedValue private Long id; private String name; // ... getters and setters}

3.1. Persistir

o método de persistência destina-se a adicionar uma nova instância da entidade ao contexto de persistência, ou seja, a transição de uma instância de estado transitório para estado persistente.

normalmente chamamos-lhe quando queremos adicionar um registo à base de dados (persistir uma instância de entidade):

Person person = new Person();person.setName("John");session.persist(person);

o que acontece depois que o método persistir é chamado? O objecto da pessoa passou de um estado transitório para um estado persistente. O objeto está no contexto de persistência agora, mas ainda não foi salvo para o banco de dados. A geração de declarações de inserção ocorrerá apenas com a transferência da transação, descarga ou fechamento da sessão.

Notice that the persistst method has void return type. Ele opera sobre o objeto passado “no lugar”, mudando seu estado. A variável pessoa referencia o objeto real persistido.

este método é uma adição posterior à interface de sessão. A principal característica de diferenciação deste método é que ele está em conformidade com a especificação JSR-220 (persistência da EJB). A semântica deste método é estritamente definida na especificação, que basicamente afirma, que:

  • uma instância transiente torna-se persistente (e a operação de cascatas de todas as suas relações com o cascade=PERSISTIREM ou cascade=TODOS),
  • se uma instância já é persistente, em seguida, esta chamada não tem qualquer efeito para esta instância específica (mas ainda cascatas de suas relações com o cascade=PERSISTIREM ou cascade=TODOS),
  • se uma instância está desligado, você deve esperar uma exceção, ou ao chamar este método, ou ao cometer ou liberação da sessão.

Notice that there is nothing here that concerns the identifier of an instance. A especificação não afirma que o id será gerado imediatamente, independentemente da estratégia de geração de id. A especificação do método persist permite à implementação emitir declarações para gerar id no commit ou flush, e o id não é garantido não ser null depois de chamar este método, então você não deve confiar nele.

você pode chamar este método em uma instância já persistente, e nada acontece. Mas se você tentar persistir uma instância separada, a implementação é obrigada a lançar uma exceção. No exemplo a seguir persistimos a entidade, despejamo-la do contexto para que se desprenda, e depois tentamos persistir novamente. A segunda chamada para a sessão.persist () causa uma exceção, de modo que o seguinte código não vai funcionar:

Person person = new Person();person.setName("John");session.persist(person);session.evict(person);session.persist(person); // PersistenceException!

3.2. Save

the save method is an “original” Hibernate method that does not conform to the JPA specification.

sua finalidade é basicamente a mesma que persiste, mas tem diferentes detalhes de implementação. A documentação para este método estritamente afirma que ele persiste a instância, “atribuindo primeiro um identificador gerado”. O método é garantido para retornar o valor serializável deste identificador.

Person person = new Person();person.setName("John");Long id = (Long) session.save(person);

o efeito de salvar uma instância já persistida é o mesmo que com a persistência. A diferença vem quando você tenta salvar uma instância separada:

Person person = new Person();person.setName("John");Long id1 = (Long) session.save(person);session.evict(person);Long id2 = (Long) session.save(person);

a variável id2 será diferente do id1. A chamada de save em uma instância destacada cria uma nova instância persistente e atribui-lhe um novo identificador, o que resulta em um registro duplicado em um banco de dados ao cometer ou flushing.

3.3. Merge

a principal intenção do método de merge é atualizar uma instância de entidade persistente com novos valores de campo de uma instância de entidade separada.

por exemplo, suponha que você tenha uma interface repousante com um método para recuperar um objeto serializado JSON por seu id para o chamador e um método que recebe uma versão atualizada deste objeto do chamador. Uma entidade que passou por tal serialização / deserialização aparecerá em um estado separado.

depois de deserializar esta instância de entidade, você precisa obter uma instância de entidade persistente a partir de um contexto de persistência e atualizar seus campos com novos valores a partir desta instância separada. Assim, o método merge faz exatamente o que:

  • encontra uma instância da entidade pela identificação de tomadas do objeto passado (ou instância de uma entidade existente a partir do contexto de persistência é recuperada, ou uma nova instância carregado a partir do banco de dados);
  • cópias campos do objeto passado para esta instância;
  • retorna recém-atualizado instância.

no exemplo seguinte, despejamos (destacar) a entidade salva do contexto, alteramos o campo Nome e, em seguida, fundimos a entidade destacada.

Person person = new Person(); person.setName("John"); session.save(person);session.evict(person);person.setName("Mary");Person mergedPerson = (Person) session.merge(person);

Note que o método de junção devolve um objecto — é o objecto de junção que foi carregado no contexto de persistência e actualizado, não o objecto de pessoa que passou como argumento. Esses são dois objetos diferentes, e o objeto da pessoa geralmente precisa ser descartado (de qualquer forma, não conte com ele sendo ligado ao contexto de persistência).

Como com persistem método, o método de impressão é especificado pela JSR-220 ter certos semântica que pode confiar:

  • se a entidade estiver desligado, ele é copiado sobre um existente persistentes da entidade;
  • se a entidade é transitório, ele é copiado sobre o recém-criado persistentes da entidade;
  • esta operação cascatas para todas as relações com cascata=INTERCALAR ou em cascata (cascade=TODOS mapeamento;
  • se a entidade é persistente, em seguida, esta chamada de método não tem efeito sobre ele (mas em cascata ainda acontece).

3.4. Update

As with persistent and save, the update method is an “original” Hibernate method that was present long before the merge method was added. Sua semântica é diferente em vários pontos-chave:

  • ele age sobre passado (objeto de seu tipo de retorno é void); o método de atualização de transições que o objeto passado a partir destacado para o estado persistente;
  • este método lança uma exceção se a passagem de uma entidade transitória.

no exemplo a seguir, salvamos o objeto, então o expulsamos do contexto, em seguida, alteramos seu nome e atualização de chamadas. Observe que não colocamos o resultado da operação de atualização em uma variável separada, porque a atualização ocorre no objeto da pessoa em si. Basicamente, estamos a recolocar a instância de entidade existente no contexto de persistência-algo que a especificação da APP não nos permite fazer.

Person person = new Person();person.setName("John");session.save(person);session.evict(person);person.setName("Mary");session.update(person);

tentar chamar a atualização em uma instância transitória resultará em uma exceção. O seguinte não funcionará:

Person person = new Person();person.setName("John");session.update(person); // PersistenceException!

3.5. SaveOrUpdate

este método aparece apenas na API Hibernada e não tem a sua contrapartida padronizada. Similar ao update, também pode ser usado para recolocar instâncias.

na verdade, a classe DefaultUpdateEventListener interna que processa o método de atualização é uma subclasse de DefaultSaveOrUpdateListener, apenas sobrepondo algumas funcionalidades. A principal diferença do método saveOrUpdate é que ele não abre exceção quando aplicado a uma instância transitória; em vez disso, torna esta instância transitória persistente. O código seguinte irá persistir uma instância recém-criada de pessoa:

Person person = new Person();person.setName("John");session.saveOrUpdate(person);

pode pensar neste método como uma ferramenta universal para tornar um objeto persistente, independentemente do seu estado, seja ele transitório ou separado.

o que utilizar?

se você não tem quaisquer requisitos especiais, como regra geral, você deve manter os métodos persistir e mesclar, porque eles são padronizados e garantidos de acordo com a especificação da App.

eles também são portáteis no caso de você decidir mudar para outro provedor de persistência, mas eles podem às vezes não parecer tão útil como os métodos “originais” hibernar, salvar, atualizar e saveOrUpdate.

Conclusion

we’ve discussed the purpose of different Hibernate Session methods in relation to managing persistent entities in runtime. Aprendemos como esses métodos de entidades transistam instâncias através de seus ciclos de vida e por que alguns desses métodos duplicaram a funcionalidade.



+