Eu vi spring.jpa.open-in-view=true
propriedade na documentação do Spring Boot para configuração JPA.
- É o
true
valor padrão para esta propriedade se não for fornecido ?; - O que isso realmente faz? Não achei nenhuma boa explicação para isso;
- Faz você usar em
SessionFactory
vez deEntityManagerFactory
? Se sim, como posso dizer para permitir que eu useEntityManagerFactory
?
Obrigado!
java
spring
jpa
spring-boot
spring-data
Carlos Alberto
fonte
fonte
O OSIV Anti-Padrão
Em vez de deixar a camada de negócios decidir como é melhor buscar todas as associações que são necessárias para a camada de Visualização, OSIV (Sessão Aberta na Visualização) força o Contexto de Persistência a permanecer aberto para que a camada de Visualização possa acionar a inicialização do Proxy, conforme ilustrado pelo diagrama a seguir.
OpenSessionInViewFilter
chama oopenSession
método do subjacenteSessionFactory
e obtém um novoSession
.Session
está vinculado aoTransactionSynchronizationManager
.OpenSessionInViewFilter
chamadoFilter
dajavax.servlet.FilterChain
referência do objeto e a solicitação é processada posteriormenteDispatcherServlet
é chamado e encaminha a solicitação HTTP para o subjacentePostController
.PostController
chama oPostService
para obter uma lista dePost
entidades.PostService
abre uma nova transação eHibernateTransactionManager
reutiliza a mesmaSession
que foi aberta peloOpenSessionInViewFilter
.PostDAO
busca a lista dePost
entidades sem inicializar qualquer associação preguiçosa.PostService
confirma a transação subjacente, masSession
não é fechado porque foi aberto externamente.DispatcherServlet
começa a renderizar a IU, que, por sua vez, navega pelas associações lazy e aciona sua inicialização.OpenSessionInViewFilter
pode fechar oSession
e a conexão de banco de dados subjacente também é liberada.À primeira vista, pode não parecer uma coisa terrível de se fazer, mas, uma vez que você vê da perspectiva do banco de dados, uma série de falhas começa a se tornar mais óbvia.
A camada de serviço abre e fecha uma transação de banco de dados, mas depois disso, não há nenhuma transação explícita acontecendo. Por esse motivo, cada instrução adicional emitida na fase de renderização da IU é executada no modo de confirmação automática. A confirmação automática pressiona o servidor de banco de dados porque cada instrução deve liberar o log de transações para o disco, causando, portanto, muito tráfego de E / S no lado do banco de dados. Uma otimização seria marcar o
Connection
como somente leitura, o que permitiria ao servidor de banco de dados evitar a gravação no log de transações.Não há mais separação de interesses porque as instruções são geradas tanto pela camada de serviço quanto pelo processo de renderização da IU. Escrever testes de integração que afirmam o número de instruções que estão sendo geradas requer passar por todas as camadas (web, serviço, DAO) enquanto o aplicativo é implantado em um contêiner da web. Mesmo ao usar um banco de dados na memória (por exemplo, HSQLDB) e um servidor web leve (por exemplo, Jetty), esses testes de integração serão mais lentos para executar do que se as camadas fossem separadas e os testes de integração de back-end usassem o banco de dados, enquanto o Os testes de integração front-end estavam zombando da camada de serviço como um todo.
A camada de IU é limitada a associações de navegação que podem, por sua vez, acionar N + 1 problemas de consulta . Embora o Hibernate ofereça
@BatchSize
associações de busca em lotes eFetchMode.SUBSELECT
para lidar com este cenário, as anotações estão afetando o plano de busca padrão, portanto, são aplicadas a todos os casos de uso de negócios. Por esse motivo, uma consulta da camada de acesso a dados é muito mais adequada porque pode ser adaptada aos requisitos atuais de busca de dados do caso de uso.Por último, mas não menos importante, a conexão com o banco de dados é mantida durante toda a fase de renderização da IU, o que aumenta o tempo de concessão da conexão e limita o rendimento geral da transação devido ao congestionamento no conjunto de conexões do banco de dados. Quanto mais a conexão for mantida, mais outras solicitações simultâneas irão esperar para obter uma conexão do pool.
Spring Boot e OSIV
Infelizmente, OSIV (Open Session in View) é habilitado por padrão no Spring Boot , e OSIV é realmente uma má ideia do ponto de vista de desempenho e escalabilidade .
Portanto, certifique-se de que, no
application.properties
arquivo de configuração, você tenha a seguinte entrada:Isso desabilitará o OSIV para que você possa lidar da
LazyInitializationException
maneira certa .A partir da versão 2.0, o Spring Boot emite um aviso quando o OSIV está habilitado por padrão, para que você possa descobrir esse problema muito antes que ele afete um sistema de produção.
Para obter mais detalhes sobre OSIV, consulte este artigo .
fonte