Em relação ao problema de hibernação encontrado ontem pelos meus colegas. É a coisa mais básica da hibernação. Entendo que muitas pessoas encontraram esse problema e é muito comum, mas muitas vezes ficam confusas ao encontrá-lo.
Para aprofundar a impressão, saiba o que é e por que é assim.
Depois disso, simplesmente usei o framework Hibernate original para fazer algumas verificações, abri o console de impressão SQL de execução e cheguei à conclusão:
A premissa é que no meio da mesma transação:
1. Use a instrução sql, session.createSQLQuery(sql).executeUpdate(); para inserir, e a estação de saída imprimirá a instrução de inserção sql e então usará a instrução sql para executar session.createSQLQuery(sql).uniqueResult(); ; e a consulta SQL também será impressa, não há problema e os dados podem ser consultados.
2. Use hibernate para encapsular a operação e use session.save(entity); para inserir. O console de saída não imprime a instrução SQL inserida. também não imprime a instrução de consulta SQL, mas os dados podem ser consultados. Quando a instrução de confirmação da transação é executada, a instrução SQL inserida é impressa
3. Use session.save(entity); do hibernate para inserir e, em seguida, use a instrução "HQL" para consultar.
4. Use session.save(entity); do hibernate para inserir, mas o console de saída não imprime a instrução SQL inserida. Em seguida, use a instrução sql para executar session.createSQLQuery(sql).uniqueResult() e a instrução de consulta SQL será impressa. Ocorreu um problema, nenhum dado pôde ser consultado. Neste caso, use o método session.flush(), execute o método flush() antes de consultar e o console de saída imprimirá a instrução SQL inserida. Se você consultar novamente, terá dados.
Após a conclusão da verificação, verifiquei as informações acima. Em relação ao quarto ponto, ele apareceu com frequência durante o processo de desenvolvimento. Acredito que muitas pessoas o tenham encontrado, mas muitas pessoas continuam confusas. Isso apenas aprofundou a impressão.
No console de impressão SQL, podemos ver o processo de operação de um método básico de hibernação:
1. Determine se a instância a ser salva já está em estado persistente e, caso contrário, coloque-a no cache;
2. Planeje uma instrução sql de inserção com base na instância a ser salva. Observe que ela é apenas planejada e não executada;
3. A instrução insert planejada anteriormente é executada quando a transação é confirmada;
Substitua tx.commit() por session.flush. Neste momento, o controle imprime a instrução insert, mas nenhum novo registro é adicionado ao banco de dados;
A principal função do método flush é limpar o cache e forçar o banco de dados a sincronizar com o cache do Hibernate para garantir a consistência dos dados. Sua principal ação é enviar uma série de instruções SQL ao banco de dados e executar essas instruções SQL, mas não as enviará ao banco de dados. O método commit chamará primeiro o método flush e depois confirmará a transação. É por isso que o registro não é inserido no banco de dados quando apenas chamamos flush, porque as atualizações no banco de dados não serão salvas até que a transação seja confirmada. Como o método commit chama implicitamente flush, geralmente não chamamos o método flush explicitamente.
Este é o mecanismo de liberação do hibernate. No processo de atualização e salvamento de alguns objetos complexos, é necessário considerar se as alterações na ordem das operações do banco de dados e se as liberações atrasadas têm impacto nos resultados do programa. Se realmente houver um impacto, você pode adicionar flush onde precisar manter a ordem das operações para forçar o Hibernate a liberar as operações registradas no cache no banco de dados. Isso pode não parecer bonito, mas é muito eficaz.
Descrição: O método session.save é colocado no cache e não pode ser descoberto pelo SQL consultando diretamente o banco de dados.
Após o método flush(), o SQL executado será impresso, mas ainda não está no banco de dados. A consulta SQL direta pode encontrar os dados.
1. Onde os dados da entidade são armazenados após flush()? O cache é igual ao método save(), portanto o SQL não deve conseguir obtê-lo.
2. Como os dados não entraram no banco de dados após o método flush, o SQL pode ser consultado diretamente usando session.createSQLQuery(sql) para consultar. Deve-se verificar diretamente se não é o banco de dados.