Est-il correct d'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?
Est-il correct d'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?
Réponses:
Non, c'est dangereux.
Malgré les meilleurs efforts de l'équipe Hibernate, vous ne pouvez tout simplement pas vous fier aux mises à jour automatiques en production . Écrivez vos propres correctifs, examinez-les avec DBA, testez-les, puis appliquez-les manuellement.
Théoriquement, si la mise à jour hbm2ddl fonctionnait en développement, elle devrait également fonctionner en production. Mais en réalité, ce n'est pas toujours le cas.
Même si cela fonctionnait bien, il pourrait ne pas être optimal. Les DBA sont payés autant pour une raison.
Nous le faisons en production, bien qu'avec une application qui ne soit pas critique pour la mission et sans DBA hautement rémunéré sur le personnel. C'est juste un processus manuel de moins qui est sujet à une erreur humaine - l'application peut détecter la différence et faire la bonne chose, et 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 en même temps et essayer de modifier le schéma, ce qui pourrait être mauvais. Ou mettez dans un mécanisme où 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 dans leur livre "Java Persistence with Hibernate" :
AVERTISSEMENT: nous avons vu des utilisateurs d'Hibernate essayer d'utiliser SchemaUpdate pour mettre à jour automatiquement le schéma d'une base de données de production. Cela peut rapidement se terminer en cas de 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é avant cette année, mais j'ai trouvé qu'il était très facile à apprendre et à rendre le contrôle de révision / migration / gestion des modifications de base de données très infaillible. Je travaille sur un projet Groovy / Grails, et Grails utilise Hibernate en dessous pour tout son ORM (appelé "GORM"). Nous utilisons Liquibase pour gérer toutes les modifications 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 modifications que vous continuez d'ajouter à mesure que votre application évolue. Ce fichier est conservé dans git (ou tout 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é, puis il applique intelligemment les changements qui n'ont pas encore été appliqués à partir du fichier. Cela fonctionne très bien 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 retirez et déployez sera toujours en mesure de se connecter à un schéma de base de données entièrement compatible.
Ce qui est génial, c'est que je peux prendre une base de données mysql complètement vierge sur mon ordinateur portable, lancer l'application et tout de suite le schéma est configuré pour moi. Il permet également de tester facilement les modifications de schéma en les appliquant d'abord à un développeur local ou à une base de données intermédiaire.
Le moyen le plus simple de commencer serait probablement de prendre votre base de données existante, puis d'utiliser Liquibase pour générer un fichier baseline.xml initial. À l'avenir, vous pourrez simplement y ajouter et laisser Liquibase prendre en charge la gestion des modifications de schéma.
hbm2ddl.auto=update
pour que vos mappages de classe / DB soient validés et que vous ayez un contrôle complet de la création de DB via liquibase. Qu'est-ce que tu penses?
validate
Je voterais non. Hibernate ne semble pas comprendre quand les types de données des colonnes ont changé. Exemples (en 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 existe probablement d'autres exemples également, tels que l'augmentation de la longueur d'une colonne String sur 255 et sa conversion en texte, texte moyen, etc.
Certes, je ne pense pas qu'il existe vraiment un moyen de "convertir les types de données" sans créer une nouvelle colonne, copier les données et effacer l'ancienne colonne. Mais à la minute où votre base de données contient des colonnes qui ne reflètent pas le mappage Hibernate actuel, vous vivez très dangereusement ...
La voie de migration est une bonne option pour résoudre ce problème:
@Column(length = 45)
à @Column(length = 255)
. Peut vérifier qu'Hibernate 4.3.6.Final a correctement mis à jour le schéma de base de données à l'aide de hbm2ddl.auto=update
. (Une chose à mentionner est que la base de données ne contient actuellement aucune donnée - seulement la structure.)
Hibernate doit mettre en garde sur le fait de ne pas utiliser les mises à jour automatiques dans prod pour se couvrir lorsque des personnes qui ne savent pas ce qu'elles font l'utilisent dans des situations où elles ne devraient pas être utilisées.
Certes, les situations où il ne devrait pas être utilisé sont beaucoup plus nombreuses que celles où il est OK.
Je l'utilise depuis des années sur de nombreux projets différents et je n'ai jamais eu un seul problème. Ce n'est pas une réponse boiteuse, et ce n'est pas du codage cowboy. C'est un fait historique.
Une personne qui dit "ne jamais le faire en production" pense à un ensemble spécifique de déploiements de production, à savoir ceux qu'il connaît (son entreprise, son industrie, etc.).
L'univers des «déploiements de production» est vaste et varié.
Un développeur Hibernate expérimenté sait exactement ce que DDL va résulter d'une configuration de mappage donnée. Tant que vous testez et validez que ce que vous attendez se retrouve dans la DDL (en dev, qa, staging, etc.), tout va bien.
Lorsque vous ajoutez de nombreuses fonctionnalités, les mises à jour automatiques du schéma peuvent être un gain de temps réel.
La liste des choses que les mises à jour automatiques ne géreront pas est infinie, mais certains exemples sont la migration des données, l'ajout de colonnes non nullables, les changements de nom de colonne, etc., etc.
Vous devez également faire attention dans les environnements en cluster.
Mais là encore, si vous saviez tout cela, vous ne poseriez pas cette question. Hmm. . . OK, si vous posez cette question, vous devez attendre d'avoir beaucoup d'expérience avec Hibernate et les mises à jour de schéma automatique avant de penser à l'utiliser dans prod.
Comme je l'ai expliqué dans cet article , ce n'est pas une bonne idée d'utiliser hbm2ddl.auto
en production.
La seule façon de gérer le schéma de base de données consiste à utiliser des scripts de migration incrémentielle car:
Même le Guide de l'utilisateur d'Hibernate vous conseille d'éviter d'utiliser l' hbm2ddl
outil pour les environnements de production.
SchemaExport
comme démontré par ce cas de test .
Nous le faisons dans un projet en cours de production depuis des mois maintenant et n'avons jamais eu de problème jusqu'à présent. Gardez à l'esprit les 2 ingrédients nécessaires à cette recette:
Concevez votre modèle d'objet avec une approche de compatibilité descendante, c'est-à-dire de désapprouver des objets et des attributs plutôt que de les supprimer / les modifier. Cela signifie que si vous devez changer le nom d'un objet ou d'un attribut, laissez l'ancien tel quel, ajoutez le nouveau et écrivez une sorte de script de migration. Si vous devez modifier une association entre des objets, si vous êtes déjà en production, cela signifie que votre conception était incorrecte en premier lieu, alors essayez de penser à une nouvelle façon d'exprimer la nouvelle relation, sans affecter les anciennes données.
Sauvegardez toujours la base de données avant le déploiement.
Mon sentiment est - après avoir lu ce post - que 90% des personnes prenant part à cette discussion sont horrifiées juste à l'idée d'utiliser des automatisations comme celle-ci dans un environnement de production. Certains lancent le ballon au DBA. Prenez un moment pour considérer que tous les environnements de production ne fourniront pas un DBA et que peu d'équipes de développement sont en mesure d'en acheter un (au moins pour les projets de taille moyenne). Donc, si nous parlons d'équipes où tout le monde doit tout faire, le ballon 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 minutieux, peut vous aider dans de nombreuses situations. Et croyez-moi, les administrateurs peuvent être difficiles à convaincre au départ, mais s'ils savent que le ballon n'est pas entre leurs mains, ils vont l'adorer.
Personnellement, je ne reviendrais 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 plus que bientôt, toutes ces opérations basées sur un schéma appartiendront au passé, il vaut donc mieux commencer à changer de perspective et à regarder vers l'avenir.
Je ne le risquerais pas car vous pourriez perdre des données qui auraient dû être préservées. hbm2ddl.auto = update est un moyen purement simple de maintenir votre base de données de développement à jour.
Dans mon cas (Hibernate 3.5.2, Postgresql, Ubuntu), le réglage hibernate.hbm2ddl.auto=update
n'a créé que de nouvelles tables et créé de nouvelles colonnes dans des tables déjà existantes.
Il n'a ni supprimé les tables, ni supprimé les colonnes, ni modifié les colonnes. Cela peut être appelé une option sûre, mais quelque chose comme hibernate.hbm2ddl.auto=create_tables add_columns
cela serait plus clair.
Ce n'est pas sûr, ce n'est 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:
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 recommande:
Et, différent des autres articles, je ne pense pas que la mise à jour automatique activée soit liée aux DBA "très bien payés" (comme mentionné dans d'autres articles). Les administrateurs de base de données ont plus de choses à faire que d'écrire des instructions SQL pour créer / modifier / supprimer des tables et des colonnes. Ces tâches quotidiennes simples peuvent être effectuées et automatisées par les développeurs et transmises uniquement à l'équipe DBA pour examen, sans avoir besoin qu'Hibernate et DBA soient "très bien payés" pour les écrire.
En règle générale, les applications d'entreprise dans les grandes organisations s'exécutent avec des privilèges réduits.
Le nom d'utilisateur de la base de données peut ne pas avoir le DDL
privilège d'ajouter des colonnes, ce qui hbm2ddl.auto=update
nécessite.
Je suis d'accord avec Vladimir. Les administrateurs de mon entreprise n'apprécieraient certainement pas si je proposais même un tel cours.
De plus, la création d'un script SQL au lieu de faire aveuglément confiance à Hibernate vous donne la possibilité de supprimer les 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 un meilleur aperçu du wat que vous avez modifié dans le modèle de données. Vous le savez, bien sûr, parce que vous l'avez fait, mais maintenant vous voyez tous les changements en une seule fois. Même ceux qui vous font aller comme "What the diable?!".
Il existe des outils qui peuvent créer un delta de schéma pour vous, donc ce n'est même pas 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 être dans des versions différentes, vous devriez avoir un moyen de vous assurer que votre application, une sorte d'outil ou de script est capable de migrer le schéma et les données d'une version pas à pas vers une suivante.
Avoir toute votre persévérance dans les mappages (ou annotations) 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 a plusieurs aspects à considérer:
é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 de mise en veille prolongée sont importants en particulier au cas où (comme dans mon expérience) vous avez différentes versions de la même application sur de nombreux types de bases de données différents.
Le point 3 est très sensible dans le cas où vous utilisez Hibernate, comme dans le cas où vous introduisez une nouvelle propriété booléenne ou numérique, si Hibernate trouvera une valeur nulle dans ces colonnes, si lèvera une exception.
Donc, ce que je ferais, c'est: utilisez effectivement la capacité des outils Hibernate de mise à jour du schéma, mais vous devez ajouter à côté de lui des rappels de maintenance de données et de schéma, comme pour remplir les valeurs par défaut, supprimer les colonnes qui ne sont plus utilisées, etc. De cette façon, vous obtenez les avantages (scripts de mise à jour du schéma indépendants de la base de données et évitez le codage dupliqué des mises à jour, dans la pérennité et dans les 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 (d'où une colonne), qui peut par défaut être nulle, avec la mise à jour automatique, vous aurez terminé. Là où plus de complexité est nécessaire, plus de travail sera nécessaire.
Cela suppose que l'application mise à jour est capable de mettre à jour son schéma (cela peut être fait), ce qui signifie également qu'elle doit avoir les droits d'utilisateur pour le faire sur le schéma. Si la politique du client empêche cela (cas probable de Lizard Brain), vous devrez fournir les scripts spécifiques à la base de données.