Respostas:
O esvaziamento da sessão força o Hibernate a sincronizar o estado na memória do Session
com o banco de dados (ou seja, para gravar alterações no banco de dados). Por padrão, o Hibernate irá liberar as alterações automaticamente para você:
Permitir limpar explicitamente o Session
fornece um controle mais preciso que pode ser necessário em algumas circunstâncias (para obter um ID atribuído, para controlar o tamanho da Sessão, ...).
id = session.save(obj);
e a transação é confirmada na próxima linha, mas o obj não está sendo salvo para DB, por quê? 2) Salvei obj usando session.save(obj);
com commit e ao retornar usei return obj.getprimaryID();
Neste caso, obj é salvo no DB. Então, por que esse comportamento está acontecendo?
Como corretamente dito nas respostas acima, ao chamar flush()
, forçamos o hibernate a executar os comandos SQL no banco de dados. Mas entenda que as mudanças ainda não foram "confirmadas". Então, depois de fazer o flush e antes de fazer o commit, se você acessar o banco de dados diretamente (digamos do prompt do SQL) e verificar as linhas modificadas, NÃO verá as mudanças.
Isso é o mesmo que abrir 2 sessões de comando SQL. E as alterações feitas em 1 sessão não são visíveis para os outros até que sejam confirmadas.
Só sei que quando chamamos session.flush()
nossas instruções são executadas no banco de dados, mas não confirmadas.
Suponha que não chamemos o flush()
método no objeto de sessão e se chamarmos o método commit, ele fará internamente o trabalho de executar instruções no banco de dados e, em seguida, confirmar.
commit=flush+commit
(em caso de funcionalidade)
Portanto, concluo que, quando chamamos o método flush () no objeto Session, ele não obtém o commit, mas atinge o banco de dados e executa a consulta e também obtém o rollback.
Para confirmar, usamos commit () no objeto Transaction.
Liberar a sessão faz com que os dados que estão atualmente na sessão sejam sincronizados com os que estão no banco de dados.
Mais no site do Hibernate:
flush()
é útil, porque não há absolutamente nenhuma garantia sobre quando a Sessão executa as chamadas JDBC, apenas a ordem em que são executadas - exceto você usa flush()
.
Você pode usar flush
para forçar as restrições de validação a serem realizadas e detectadas em um local conhecido, em vez de quando a transação for confirmada. Pode ser quecommit
seja chamado implicitamente por alguma lógica de estrutura, por meio de lógica declarativa, o contêiner ou por um modelo. Nesse caso, qualquer exceção lançada pode ser difícil de capturar e manipular (pode ser muito alta no código).
Por exemplo, se você save()
um novo objeto EmailAddress, que tem uma restrição exclusiva no endereço, não receberá um erro até que faça o commit.
Chamar flush()
força a inserção da linha, lançando uma exceção se houver uma duplicata.
No entanto, você terá que reverter a sessão após a exceção.
Eu gostaria apenas de combinar todas as respostas fornecidas acima e também relacionar o método Flush () com Session.save () para dar mais importância
Hibernate save () pode ser usado para salvar a entidade no banco de dados. Podemos invocar esse método fora de uma transação, por isso não gosto desse método para salvar dados. Se usarmos isso sem transação e tivermos cascateamento entre entidades, apenas a entidade primária será salva, a menos que liberemos a sessão.
flush (): Força o esvaziamento da sessão. É usado para sincronizar os dados da sessão com o banco de dados.
Quando você chama session.flush (), as instruções são executadas no banco de dados, mas não são confirmadas. Se você não chamar session.flush () e se você chamar session.commit (), internamente o método commit () executa a instrução e confirma.
Portanto, commit () = flush + commit. Portanto, session.flush () apenas executa as instruções no banco de dados (mas não confirma) e as instruções NÃO ESTÃO mais NA MEMÓRIA. Ele apenas força o esvaziamento da sessão.
Alguns pontos importantes:
Devemos evitar salvar fora do limite da transação, caso contrário, as entidades mapeadas não serão salvas, causando inconsistência de dados. É muito normal esquecer a liberação da sessão porque isso não lança nenhuma exceção ou aviso. Por padrão, o Hibernate irá liberar as alterações automaticamente para você: antes de algumas execuções de consulta quando uma transação é confirmada. Permitir limpar explicitamente a Sessão oferece um controle mais preciso que pode ser necessário em algumas circunstâncias (para obter um ID atribuído, para controlar o tamanho da Sessão )
O flush()
método faz com que o Hibernate libere a sessão. Você pode configurar o Hibernate para usar o modo de liberação para a sessão usando o setFlushMode()
método. Para obter o modo de liberação para a sessão atual, você pode usar o getFlushMode()
método. Para verificar se a sessão está suja, você pode usarisDirty()
método. Por padrão, o Hibernate gerencia a liberação das sessões.
Conforme indicado na documentação:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
Rubor
Flushing é o processo de sincronizar o estado do contexto de persistência com o banco de dados subjacente. O
EntityManager
e o HibernarSession
expõem um conjunto de métodos, através dos quais o desenvolvedor da aplicação pode alterar o estado persistente de uma entidade.O contexto de persistência atua como um cache write-behind transacional, enfileirando qualquer mudança de estado de entidade. Como qualquer cache write-behind, as alterações são primeiro aplicadas na memória e sincronizadas com o banco de dados durante o tempo de liberação. A operação de liberação pega cada mudança de estado de entidade e a traduz em um
INSERT
,UPDATE
ouDELETE
declaração.A estratégia de liberação é fornecida pelo flushMode da Sessão do Hibernate em execução no momento. Embora JPA defina apenas duas estratégias de liberação (
AUTO
eCOMMIT
), o Hibernate tem um espectro muito mais amplo de tipos de liberação :
ALWAYS
: Libera a sessão antes de cada consulta;AUTO
: Este é o modo padrão e ele libera a Sessão apenas se necessário;COMMIT
: A Sessão tenta atrasar a liberação até que a Transação atual seja confirmada, embora também possa ser liberada prematuramente;MANUAL
: A liberação de sessão é delegada ao aplicativo, que deve ser chamadoSession.flush()
explicitamente para aplicar as alterações de contexto de persistência.Por padrão, o Hibernate usa o
AUTO
modo de descarga que dispara uma descarga nas seguintes circunstâncias:
- antes de comprometer uma Transação;
- antes de executar uma consulta JPQL / HQL que se sobrepõe às ações da entidade enfileirada;
- antes de executar qualquer consulta SQL nativa que não tenha sincronização registrada.
Ligar EntityManager#flush
tem efeitos colaterais . Ele é convenientemente usado para tipos de entidade com valores de ID gerados (valores de sequência): tal ID está disponível apenas na sincronização com a camada de persistência subjacente. Se esse ID for necessário antes que a transação atual termine (para fins de registro, por exemplo), é necessário liberar a sessão.