Comment la propriété spring.jpa.hibernate.ddl-auto fonctionne-t-elle exactement au printemps?

129

Je travaillais sur mon projet d'application Spring Boot et j'ai remarqué que, parfois, il y a une erreur de délai de connexion à ma base de données sur un autre serveur (SQL Server). Cela se produit spécialement lorsque j'essaie de faire une migration de script avec, FlyWaymais cela fonctionne après plusieurs essais.

Ensuite, j'ai remarqué que je n'ai pas spécifié spring.jpa.hibernate.ddl-autodans mon fichier de propriétés. J'ai fait quelques recherches et j'ai trouvé qu'il était recommandé d'ajouter spring.jpa.hibernate.ddl-auto= create-dropdu développement. Et changez-le en: spring.jpa.hibernate.ddl-auto= noneen production.

Mais je n'ai pas vraiment compris comment cela fonctionne vraiment et comment hibernate génère-t-il un schéma de base de données en utilisant create-dropou nonevalue. Pouvez-vous s'il vous plaît expliquer techniquement comment cela fonctionne vraiment, et quelles sont les recommandations pour l'utilisation de cette propriété en développement et sur un serveur de production. Je vous remercie

METTAIBI
la source
1
FWIW JPA 2.1 a une propriété standard javax.persistence.schema-generation.database.action donc ne voyez pas vraiment la nécessité d'utiliser les propriétés spécifiques du fournisseur JPA pour la génération de schémas.
Neil Stockton
@NeilStockton Une idée que nous explorons avec Hibernate 6 est la possibilité de contrôler la génération de schémas différemment en fonction des catégories; Par exemple, vos tables orm pourraient l'être, nonemais vous voudrez peut-être que vos tables Hibernate Search et Envers soient générées en utilisant updatepuisqu'elles sont gérées en interne par ces projets et que vous ne voulez pas les gérer manuellement vous-même. À l'heure actuelle, nous contrôlons cela globalement pour toutes les tables, quelle que soit leur origine / source. Cela renforcerait la raison d'utiliser des options spécifiques au fournisseur si vous vouliez l'utiliser.
Naros

Réponses:

215

Pour mémoire, la spring.jpa.hibernate.ddl-autopropriété est spécifique JPA des données Spring et est leur façon de spécifier une valeur qui finira par être transmis à Hibernate sous la propriété , il sait, hibernate.hbm2ddl.auto.

Les valeurs create, create-drop, validateet updateessentiellement influencent la façon dont la gestion des outils de schéma va manipuler le schéma de base de données au démarrage.

Par exemple, l' updateopération interrogera l'API du pilote JDBC pour obtenir les métadonnées de la base de données, puis Hibernate compare le modèle d'objet qu'il crée en fonction de la lecture de vos classes annotées ou des mappages XML HBM et tentera d'ajuster le schéma à la volée.

L' updateopération, par exemple, tentera d'ajouter de nouvelles colonnes, contraintes, etc. mais ne supprimera jamais une colonne ou une contrainte qui aurait pu exister auparavant mais qui ne fait plus partie du modèle objet d'une exécution précédente.

En règle générale, dans les scénarios de scénario de test, vous l'utiliserez probablement create-droppour créer votre schéma, votre scénario de test ajoute des données fictives, vous exécutez vos tests, puis pendant le nettoyage du scénario de test, les objets de schéma sont supprimés, laissant une base de données vide.

En développement, il est souvent courant de voir les développeurs utiliser updatepour modifier automatiquement le schéma pour ajouter de nouveaux ajouts au redémarrage. Mais encore une fois, comprenez que cela ne supprime pas une colonne ou une contrainte pouvant exister lors d'exécutions précédentes qui ne sont plus nécessaires.

En production, il est souvent fortement recommandé d'utiliser noneou simplement de ne pas spécifier cette propriété. En effet, il est courant pour les administrateurs de base de données d'examiner les scripts de migration pour les modifications de base de données, en particulier si votre base de données est partagée entre plusieurs services et applications.

Naros
la source
11
Ouais, n'utilisez jamais la génération ddl en production. Nous générons les scripts initiaux pour la structure de la table à l'aide de ddl et impliquons le DBA dans le processus. Nous incluons ensuite les scripts db dans le cadre de l'unité de déploiement, et les exécutons à l'aide de Flyway lorsque l'application est déployée. Lorsque nous avons besoin de modifier la base de données, nous ajoutons de nouveaux scripts à la prochaine version de l'application et nous déployons en staging. Flyway détectera automatiquement la version actuelle et exécutera les scripts nécessaires pour amener la base de données à la version la plus récente. Si tout fonctionne, nous déployons en production.
Klaus Groenbaek
1
et si nous ne spécifions pas cette propriété? par exemple, j'ai ma propre <bean id = "sessionFactory" class = "org.springframework.orm.hibernate5.LocalSessionFactoryBean"> ... <prop key = "hibernate.hbm2ddl.auto"> mise à jour </prop> J'avais ceci et pour une raison quelconque, mes tables étaient toujours supprimées, jusqu'à ce que j'aie ajouté la propriété mentionnée ci-dessus ;; ps: désolé pour l'exemple de code)
Ţîgan Ion
11
Pourquoi pas validatedans Production Env?
Shamal Karunarathne
20
@ShamalKarunarathne Les applications peuvent être utilisées validateen production, mais il s'agit généralement d'un paramètre que vous utilisez dans votre environnement de qualité / test pour vérifier que les scripts de base de données que vous avez écrits ou appliqués à votre outil de migration de base de données sont précis. Une autre raison de ne pas l'utiliser validateen production est que cela pourrait être un goulot d'étranglement pendant le processus de démarrage de votre application, en particulier si votre modèle objet est assez volumineux ou si d'autres facteurs liés au réseau entrent en jeu.
Naros
1
Sans une pile précise, il est difficile de spéculer; cependant, ma première hypothèse serait qu'il orderest mal interprété par l'analyseur SQL puisque c'est un mot clé s'il n'est pas échappé.
Naros