Puis-je exécuter des applications Hibernate configurées avec hbm2ddl.auto=update
pour mettre à jour le schéma de base de données dans un environnement de production?
Non, c'est dangereux.
Malgré tous les efforts de l’équipe Hibernate, vous ne pouvez tout simplement pas compter sur des mises à jour automatiques en production. Écrivez vos propres correctifs, passez-les en revue avec DBA, testez-les, puis appliquez-les manuellement.
Théoriquement, si mise à jour de hbm2ddl a fonctionné en développement, il devrait également fonctionner en production. Mais en réalité, ce n'est pas toujours le cas.
Même si cela a fonctionné correctement, cela peut être sous-optimal. Les DBA sont payés autant pour une raison.
Nous le faisons en production, mais avec une application qui n’est pas critique et sans aucun administrateur de base hautement rémunéré. Il s’agit là d’un processus manuel de moins sujet aux erreurs humaines: l’application peut détecter la différence et faire le bon choix, sans compter que vous l’avez probablement testée dans divers environnements de développement et de test.
Une mise en garde - dans un environnement en cluster, vous voudrez peut-être l'éviter car plusieurs applications peuvent apparaître simultanément et essayer de modifier le schéma, ce qui pourrait être mauvais. Vous pouvez également mettre en place un mécanisme dans lequel une seule instance est autorisée à mettre à jour le schéma.
Les créateurs d'Hibernate déconseillent de le faire dans un environnement de production de leur livre "Java Persistence with Hibernate" :
AVERTISSEMENT: des utilisateurs d'Hibernate ont essayé d'utiliser SchemaUpdate pour mettre à jour automatiquement le schéma d'une base de données de production. Cela peut rapidement se terminer en catastrophe et ne sera pas autorisé par votre administrateur de base de données.
Consultez LiquiBase XML pour conserver un journal des mises à jour. Je ne l'avais jamais utilisé jusqu'à cette année, mais j'ai découvert qu'il était très facile à apprendre et à rendre le contrôle de révision/migration/gestion de révision de base de données très fiable. Je travaille sur un projet Groovy/Grails, et Grails utilise Hibernate pour tous ses ORM (appelés "GORM"). Nous utilisons Liquibase pour gérer tous les changements de schéma SQL, ce que nous faisons assez souvent à mesure que notre application évolue avec de nouvelles fonctionnalités.
Fondamentalement, vous conservez un fichier XML de jeux de modifications que vous continuez d'ajouter à mesure que votre application évolue. Ce fichier est conservé dans git (ou ce que vous utilisez) avec le reste de votre projet. Lorsque votre application est déployée, Liquibase vérifie sa table de journal des modifications dans la base de données à laquelle vous vous connectez afin de savoir ce qui a déjà été appliqué. Elle applique ensuite de manière intelligente les modifications qui n'ont pas encore été appliquées à partir du fichier. Cela fonctionne parfaitement dans la pratique, et si vous l’utilisez pour toutes vos modifications de schéma, vous pouvez être sûr à 100% que le code que vous extrayez et déployez sera toujours capable de se connecter à un schéma de base de données entièrement compatible.
Ce qui est génial, c’est que je puisse prendre une base de données mysql totalement vierge sur mon ordinateur portable, lancer l’application, et tout de suite le schéma est configuré pour moi. Cela facilite également le test des modifications de schéma en les appliquant d’abord à une base de développement ou à une base de données intermédiaire.
Le moyen le plus simple de démarrer avec ce logiciel serait probablement d'utiliser votre base de données existante, puis d'utiliser Liquibase pour générer un fichier initial baseline.xml. Dans le futur, vous pourrez simplement l’annexer et laisser liquibase prendre en charge la gestion des modifications de schéma.
Hibernate doit mettre en garde de ne pas utiliser les mises à jour automatiques dans prod pour se couvrir lorsque des personnes ne sachant pas ce qu’elles font l’utilisent dans des situations où elles ne devraient pas être utilisées.
Les situations dans lesquelles il ne devrait pas être utilisé sont nettement plus nombreuses que celles où il est acceptable.
Je l'utilise depuis des années sur de nombreux projets et je n'ai jamais eu un seul problème. Ce n'est pas une réponse boiteuse, et ce n'est pas un code de cow-boy. C'est un fait historique.
Une personne qui dit "ne le faites jamais en production" songe à un ensemble spécifique de déploiements de production, à savoir ceux avec lesquels il est familier (sa société, son secteur, etc.).
L'univers des "déploiements de production" est vaste et varié.
Un développeur Hibernate expérimenté sait exactement quel type de DDL va résulter d’une configuration de mappage donnée. Tant que vous testez et validez que ce que vous attendez aboutit au DDL (dev, qa, staging, etc.), tout va bien.
Lorsque vous ajoutez de nombreuses fonctionnalités, les mises à jour automatiques des schémas peuvent vous faire gagner du temps.
La liste des choses que les mises à jour automatiques ne gèrent pas est sans fin, mais quelques exemples sont la migration de données, l'ajout de colonnes non nullables, les changements de noms de colonnes, etc., etc.
Vous devez également faire attention dans les environnements en cluster.
Mais encore une fois, si vous saviez tout cela, vous ne poseriez pas cette question. Hmm. . . OK, si vous posez cette question, attendez de nombreuses expériences avec Hibernate et les mises à jour automatiques de schémas avant de penser à l’utiliser dans prod.
Je voterais non. Hibernate ne semble pas comprendre quand les types de données des colonnes ont changé. Exemples (utilisant MySQL):
String with @Column(length=50) ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)
@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed
Il y a probablement d'autres exemples, tels que pousser la longueur d'une colonne String jusqu'à 255 et la voir convertir en texte, texte moyen, etc.
Certes, je ne pense pas qu’il existe vraiment un moyen de "convertir des types de données" sans créer une nouvelle colonne, copier les données et détruire l’ancienne colonne. Mais à la minute où votre base de données contient des colonnes ne reflétant pas la cartographie Hibernate actuelle, vous vivez de manière très dangereuse ...
Flyway est une bonne option pour traiter ce problème:
Comme je l'ai expliqué dans cet article , utiliser hbm2ddl.auto
en production n'est pas une bonne idée.
Le seul moyen de gérer le schéma de base de données consiste à utiliser des scripts de migration incrémentiels pour les raisons suivantes:
Même le Guide de l'utilisateur Hibernate vous conseille d'éviter d'utiliser l'outil hbm2ddl
pour les environnements de production.
Nous le faisons dans un projet en production depuis des mois et n’avons jamais eu de problème à ce jour. Gardez à l'esprit les 2 ingrédients nécessaires à cette recette:
Concevez votre modèle d'objet avec une approche de compatibilité ascendante, c'est-à-dire obsolète objets et attributs plutôt que de les supprimer/modifier. Cela signifie que si vous devez modifier le nom d'un objet ou d'un attribut, laissez l'ancien, maintenez-le tel quel, ajoutez-en un nouveau et écrivez un type de script de migration. Si vous devez modifier une association entre des objets, si vous êtes déjà en production, cela signifie en premier lieu que votre conception était fausse. Essayez donc de penser à une nouvelle façon d'exprimer la nouvelle relation, sans affecter les anciennes données.
Toujours sauvegarde la base de données avant le déploiement.
Mon sentiment est - après avoir lu cet article - que 90% des participants à cette discussion sont horrifiés par l'idée d'utiliser de telles automatisations dans un environnement de production. Certains lancent le ballon vers le DBA. Prenez un moment pour considérer que tous les environnements de production ne fournissent pas un administrateur de base de données et que peu d’équipes de développement sont en mesure d’en acheter un (du moins pour les projets de taille moyenne). Donc, si nous parlons d’équipes où tout le monde doit tout faire, la balle est sur elles.
Dans ce cas, pourquoi ne pas simplement essayer d’avoir le meilleur des deux mondes? Des outils comme celui-ci sont là pour vous aider, ce qui - avec une conception et un plan soignés - peut aider dans de nombreuses situations. Et croyez-moi, les administrateurs risquent d’être difficiles à convaincre au départ, mais s’ils savent que le ballon n’est pas sur leurs mains, ils vont adorer.
Personnellement, je ne recommencerais jamais à écrire des scripts à la main pour étendre n'importe quel type de schéma, mais c'est juste mon opinion. Et après avoir commencé récemment à adopter des bases de données sans schéma NoSQL, je peux voir que, très bientôt, toutes ces opérations basées sur des schémas appartiendront au passé. Vous feriez donc mieux de changer de perspective et de regarder vers l'avenir.
Je ne le risquerais pas car vous risqueriez de perdre des données qui auraient dû être préservées. hbm2ddl.auto = update est un moyen simple de garder votre base de données dev à jour.
Dans mon cas (Hibernate 3.5.2, Postgresql, Ubuntu), la définition de hibernate.hbm2ddl.auto=update
ne créait que de nouvelles tables et créait de nouvelles colonnes dans des tables déjà existantes.
Il n'a ni supprimé de tables, ni de colonnes, ni modifié de colonnes. Cela peut être appelé une option sûre, mais quelque chose comme hibernate.hbm2ddl.auto=create_tables add_columns
serait plus clair.
Ce n'est pas sûr, pas recommandé, mais c'est possible.
J'ai de l'expérience dans une application utilisant l'option de mise à jour automatique en production.
Eh bien, les principaux problèmes et risques rencontrés dans cette solution sont les suivants:
Donc, je ne recommanderai pas d'utiliser la mise à jour automatique en production.
Si vous voulez vraiment utiliser la mise à jour automatique en production, je vous recommande:
Et, différent des autres posts, je ne pense pas que la mise à jour automatique permette sa relation avec des DBA "très bien payés" (comme mentionné dans d'autres posts) ... Les DBA ont des choses plus importantes à faire que d'écrire des instructions SQL pour créer/change/delete tables et colonnes. Ces tâches simples peuvent être effectuées et automatisées par les développeurs. Elles ne sont transmises qu’à l’équipe DBA, qui n’a pas besoin d’Hibernate et des DBA "très bien payés" pour les écrire.
Non, ne le fais jamais. Hibernate ne gère pas la migration de données. Oui, cela donnera à votre schéma une apparence correcte, mais cela ne garantit pas que des données de production précieuses ne sont pas perdues au cours du processus.
Généralement, les applications d'entreprise des grandes entreprises fonctionnent avec des privilèges réduits.
Le nom d'utilisateur de la base de données peut ne pas avoir le privilège DDL
pour ajouter les colonnes nécessaires à hbm2ddl.auto=update
.
Je suis d'accord avec Vladimir. Les administrateurs de mon entreprise n’apprécieraient certainement pas si je proposais un tel cours.
De plus, créer un script SQL au lieu de faire confiance à Hibernate vous donne l’opportunité de supprimer des champs qui ne sont plus utilisés. Hibernate ne fait pas ça.
Et je trouve que la comparaison du schéma de production avec le nouveau schéma vous donne une idée encore plus précise de ce que vous avez modifié dans le modèle de données. Vous savez, bien sûr, parce que vous l'avez fait, mais maintenant, vous voyez tous les changements en une fois. Même ceux qui vous font aller comme "c'est quoi ce bordel?!".
Il existe des outils qui peuvent créer un delta de schéma pour vous, donc ce n'est pas même un travail difficile. Et puis vous savez exactement ce qui va se passer.
Le schéma des applications peut évoluer dans le temps; Si vous avez plusieurs installations, qui peuvent avoir différentes versions, vous devriez pouvoir vous assurer que votre application, un outil ou un script est capable de migrer le schéma et les données d’une version à l’autre.
Avoir toute votre persistance dans les mappages (ou annotations) d'Hibernate est un très bon moyen de contrôler l'évolution du schéma.
Vous devez considérer que l'évolution du schéma doit prendre en compte plusieurs aspects:
évolution du schéma de base de données en ajoutant plus de colonnes et de tables
suppression d'anciennes colonnes, tables et relations
remplir de nouvelles colonnes avec des valeurs par défaut
Les outils Hibernate sont importants, en particulier dans le cas (comme dans mon cas), vous avez différentes versions de la même application sur de nombreux types de bases de données.
Le point 3 est très sensible au cas où vous utiliseriez Hibernate, comme si vous introduisiez une nouvelle propriété de valeur booléenne ou numérique, si Hibernate trouverait une valeur nulle dans de telles colonnes, si une exception serait levée.
Donc, ce que je ferais, c’est utiliser la capacité de mise à jour de schéma d’Hibernate Tools, mais vous devez également ajouter un rappel de maintenance des données et du schéma, comme pour le remplissage des valeurs par défaut, la suppression des colonnes non utilisées, etc. De cette manière, vous bénéficiez d'avantages (scripts de mise à jour de schéma indépendants de la base de données et évitant le codage en double des mises à jour, en permanence et en scripts), mais vous couvrez également tous les aspects de l'opération.
Ainsi, par exemple, si une mise à jour de version consiste simplement à ajouter une propriété à valeur varchar (donc une colonne), dont la valeur par défaut peut être null, la mise à jour automatique étant terminée. Là où plus de complexité est nécessaire, plus de travail sera nécessaire.
Cela suppose que l'application mise à jour soit capable de mettre à jour son schéma (cela peut être fait), ce qui signifie également qu'elle doit disposer des droits d'utilisateur pour le faire sur le schéma. Si la politique du client l'empêche (cas probable du cas Lizard Brain), vous devrez fournir les scripts spécifiques à la base de données.