Pour une description plus longue, vous pouvez lire mon article Open Session In View Anti-Pattern . Sinon, voici un résumé des raisons pour lesquelles vous ne devriez pas utiliser Open Session In View.
Open Session In View adopte une mauvaise approche pour récupérer des données. Au lieu de laisser la couche de gestion décider de la meilleure manière d'extraire toutes les associations nécessaires à la couche de vue, elle force le contexte de persistance à rester ouvert afin que la couche de vue puisse déclencher l'initialisation du proxy.

- L' OpenSessionInViewFilterappelle laopenSessionméthode du sous-jacentSessionFactoryet obtient un nouveauSession.
- Le Sessionest lié auTransactionSynchronizationManager.
- Les OpenSessionInViewFilterappelsdoFilterde lajavax.servlet.FilterChainréférence d'objet et la demande est ensuite traitée
- Le DispatcherServletest appelé et achemine la requête HTTP vers le sous-jacentPostController.
- L' PostControllerappel lePostServicepour obtenir une liste d'Postentités.
- Le PostServiceouvre une nouvelle transaction etHibernateTransactionManagerréutilise la mêmeSessionqui a été ouverte par leOpenSessionInViewFilter.
- Le PostDAOrécupère la liste desPostentités sans initialiser aucune association paresseuse.
- Le PostServicevalide la transaction sous-jacente, maisSessionn'est pas fermé car il a été ouvert en externe.
- Le DispatcherServletcommence le rendu de l'interface utilisateur, qui, à son tour, parcourt les associations différées et déclenche leur initialisation.
- Le OpenSessionInViewFilterpeut fermer leSession, et la connexion à la base de données sous-jacente est également libérée.
À première vue, cela ne semble pas être une chose terrible à faire, mais, une fois que vous l'avez vue du point de vue d'une base de données, une série de failles commencent à devenir plus évidentes.
La couche de service ouvre et ferme une transaction de base de données, mais par la suite, aucune transaction explicite n'est en cours. Pour cette raison, chaque instruction supplémentaire émise à partir de la phase de rendu de l'interface utilisateur est exécutée en mode de validation automatique. L'auto-validation met la pression sur le serveur de base de données car chaque instruction doit vider le journal des transactions sur le disque, ce qui entraîne un trafic d'E / S important côté base de données. Une optimisation serait de marquer le Connectioncomme étant en lecture seule, ce qui permettrait au serveur de base de données d'éviter d'écrire dans le journal des transactions.
Il n'y a plus de séparation des préoccupations car les instructions sont générées à la fois par la couche de service et par le processus de rendu de l'interface utilisateur. L'écriture de tests d'intégration affirmant le nombre d'instructions générées nécessite de passer par toutes les couches (web, service, DAO), tout en déployant l'application sur un conteneur web. Même lors de l'utilisation d'une base de données en mémoire (par exemple HSQLDB) et d'un serveur Web léger (par exemple Jetty), ces tests d'intégration seront plus lents à exécuter que si les couches étaient séparées et que les tests d'intégration back-end utilisaient la base de données, tandis que le les tests d'intégration frontale se moquaient complètement de la couche de service.
La couche d'interface utilisateur est limitée à la navigation dans les associations qui peuvent, à leur tour, déclencher des problèmes de requête N + 1. Bien qu'Hibernate propose @BatchSizede récupérer les associations par lots et FetchMode.SUBSELECTde faire face à ce scénario, les annotations affectent le plan de récupération par défaut, elles sont donc appliquées à chaque cas d'utilisation métier. Pour cette raison, une requête de couche d'accès aux données est beaucoup plus appropriée car elle peut être adaptée aux exigences de récupération de données du cas d'utilisation actuel.
Enfin, la connexion à la base de données peut être maintenue tout au long de la phase de rendu de l'interface utilisateur (en fonction du mode de libération de votre connexion), ce qui augmente la durée du bail de connexion et limite le débit global des transactions en raison de la congestion du pool de connexions de la base de données. Plus la connexion est maintenue, plus d'autres requêtes simultanées vont attendre pour obtenir une connexion à partir du pool.
Donc, soit vous maintenez la connexion pendant trop longtemps, soit vous acquérez / libérez plusieurs connexions pour une seule requête HTTP, ce qui exerce une pression sur le pool de connexions sous-jacent et limite l'évolutivité.
Botte de printemps
Malheureusement, Open Session in View est activé par défaut dans Spring Boot .
Donc, assurez-vous que dans le application.propertiesfichier de configuration, vous avez l'entrée suivante:
spring.jpa.open-in-view=false
Cela désactivera OSIV, afin que vous puissiez gérer LazyInitializationExceptionla bonne manière .