Question

Puis-je exécuter les applications Hibernate configurées avec hbm2ddl.auto = update pour mettre à jour le schéma de base de données dans un environnement de production?

Était-ce utile?

La solution

Non, c'est dangereux.

Malgré les efforts de l'équipe Hibernate, vous ne pouvez tout simplement pas compter sur les 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 a fonctionné en développement, elle 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.

Autres conseils

Nous le faisons en production, mais avec une application qui n’est pas essentielle à la mission et sans aucun administrateur de base de données très bien payé. Il ne s'agit que d'un processus manuel de moins sujet aux erreurs humaines: l'application peut détecter la différence et agir correctement, 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, il peut être préférable de 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 dans leur livre & Java; Persistance Java. avec 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 aboutir à un désastre et votre administrateur de base de données ne le permettra pas.

Consultez le fichier XML LiquiBase pour conserver un journal des modifications mis à 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 toutes ses opérations ORM (appelées "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.

En principe, 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 pour 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 très bien en 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 données locale-dev ou intermédiaire.

Le moyen le plus simple de commencer à utiliser ce logiciel consiste probablement à utiliser votre base de données existante, puis à 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.

http://www.liquibase.org/

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 dans lesquelles il est OK.

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". pense à un ensemble spécifique de déploiements de production, à savoir ceux qu’il connaît (son entreprise, son secteur, etc.).

L'univers des " déploiements de production " est vaste et varié.

Un développeur Hibernate expérimenté sait exactement quel 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 le DDL (dev, qa, staging, etc.), tout va bien.

Lorsque vous ajoutez de nombreuses fonctionnalités, les mises à jour automatiques du schéma peuvent vous faire gagner du temps.

La liste des choses que les mises à jour automatiques ne géreront 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.,

.

Vous devez également faire attention dans les environnements en cluster.

Mais encore une fois, si vous saviez tout ça, 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 (avec 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, comme augmenter la longueur d'une colonne String au-dessus de 255 et la voir convertie en texte, en texte moyen, etc., etc.

Certes, je ne pense pas qu'il existe vraiment un moyen de "convertir les types de données". avec sans créer une nouvelle colonne, copier les données et éliminer 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:

http://flywaydb.org

Comme je l'ai expliqué dans cet article , ce n'est pas une bonne idée de utilisez hbm2ddl.auto en production.

Le seul moyen de gérer le schéma de base de données consiste à utiliser des scripts de migration incrémentiels, car:

  • les scripts résideront dans VCS le long de votre base de code. Lorsque vous extrayez une branche, vous recréez l'intégralité du schéma.
  • les scripts incrémentiels peuvent être testés sur un serveur d'assurance qualité avant d'être appliqués en production
  • aucune intervention manuelle n’est nécessaire, car les scripts peuvent être exécutés par Flyway , ce qui réduit les risques de erreur associée à l'exécution manuelle de scripts.

Même le Guide de l'utilisateur Hibernate vous conseillons d'éviter d'utiliser l'outil hbm2ddl pour les environnements de production.

 entrez la description de l

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.

Nous le faisons dans un projet en production depuis des mois et n’avons jamais rencontré de problème. Gardez à l’esprit les 2 ingrédients nécessaires à cette recette:

  1. Concevez votre modèle d'objet avec une approche de compatibilité ascendante, c'est-à-dire déconseiller les objets et les 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 erronée. Essayez donc de penser à une nouvelle façon d’exprimer la nouvelle relation, sans affecter les anciennes données.

  2. Toujours sauvegarder la base de données avant le déploiement.

Mon sentiment est - après lecture de 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 la balle 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 ce n'est que mon opinion. Et après avoir commencé récemment à adopter des bases de données sans schéma NoSQL, je constate que plus rapidement que jamais, 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.

  • Dans mon cas (Hibernate 3.5.2, Postgresql, Ubuntu), la définition de hibernate.hbm2ddl.auto = update n'a créé que les nouvelles tables et créé de nouvelles colonnes dans les tables 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.

Les principaux problèmes et risques rencontrés dans cette solution sont les suivants:

  • Déployez dans la mauvaise base de données . Si vous commettez l'erreur d'exécuter le serveur d'applications avec une ancienne version de l'application (EAR / WAR / etc) dans une base de données incorrecte ... Vous aurez beaucoup de nouvelles colonnes, tables, clés étrangères et erreurs. Le même problème peut survenir avec une simple erreur dans le fichier de source de données (copier / coller le fichier et avoir oublié de modifier la base de données). En résumé, la situation peut être catastrophique pour votre base de données.
  • Le démarrage du serveur d'applications est trop long . Cela se produit car Hibernate essaie de trouver toutes les tables / colonnes / etc créées à chaque démarrage de l'application. Il a besoin de savoir ce qui doit être créé (table, colonne, etc.). Ce problème ne fera qu'empirer avec la croissance des tables de la base de données.
  • Outils de base de données, il est presque impossible de les utiliser . Pour créer des scripts de base de données à exécuter avec une nouvelle version, vous devez penser à ce qui sera créé par la mise à jour automatique après le démarrage du serveur d'applications. Par exemple, si vous devez remplir une nouvelle colonne avec des données, vous devez démarrer le serveur d'applications, attendez qu'Hibernate crée la nouvelle colonne et n'exécutez le script SQL qu'après. Comme vous pouvez le constater, les outils de migration de base de données (tels que Flyway, Liquibase, etc.) sont quasiment impossibles à utiliser avec la mise à jour automatique activée.
  • Les modifications de la base de données ne sont pas centralisées . Avec la possibilité qu'Hibernate crée les tables et tout le reste, il est difficile de surveiller les modifications apportées à la base de données dans chaque version de l'application, car la plupart d'entre elles le sont automatiquement.
  • Encourage les déchets sur la base de données . En raison de la facilité de mise à jour automatique, votre équipe néglige de supprimer les anciennes colonnes et les anciennes tables.
  • Désastre imminent . Le risque imminent qu'une catastrophe se produise dans la production (comme certaines personnes mentionnées dans d'autres réponses). Même avec une application en cours d'exécution et pouvant être mise à jour pendant des années, je ne pense pas qu'elle soit sûre. Je ne me suis jamais senti en sécurité avec cette option.

Je ne recommanderai donc pas l'utilisation de la mise à jour automatique en production.

Si vous voulez vraiment utiliser la mise à jour automatique en production, je vous recommande:

  • Réseaux séparés . Votre environnement de test ne peut pas accéder à l'environnement des homologues. Cela permet d'éviter qu'un déploiement supposé se trouver dans l'environnement de test modifie la base de données d'homologation.
  • Gérer l'ordre des scripts . Vous devez organiser vos scripts pour qu'ils s'exécutent avant votre déploiement (changement de table de structure, suppression de table / colonnes) et votre script après le déploiement (informations de remplissage pour les nouvelles colonnes / tables).

Et, à la différence des autres publications, je ne pense pas que la mise à jour automatique permette sa relation avec "très bien payé". DBA (comme mentionné dans d'autres publications) ... Les DBA ont des tâches plus importantes 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 ne peuvent être 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, votre schéma aura l'air correct mais cela ne garantit pas que des données de production utiles ne seront 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 disposer du privilège DDL pour l'ajout de colonnes requises par 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 la possibilité de supprimer des champs qui ne sont plus utilisés. Hibernate ne fait pas cela.

Et je trouve que la comparaison du schéma de production avec le nouveau schéma vous donne une idée encore meilleure 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 incitent à vous dire: "Qu'est-ce qui se passe?!".

Certains outils peuvent créer un delta de schéma pour vous, ce n’est donc 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 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.

Disposer de toute votre persistance dans les mappages (ou annotations) Hibernate est un très bon moyen de contrôler l’évolution du schéma.

Vous devriez considérer que l'évolution du schéma doit prendre en compte plusieurs aspects:

  1. évolution du schéma de base de données dans ajouter plus de colonnes et de tableaux

  2. suppression d'anciennes colonnes, tableaux et relations

  3. remplir les nouvelles colonnes avec les valeurs par défaut

Les outils Hibernate sont particulièrement importants dans le cas (comme dans mon cas) de versions différentes 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 null dans ces colonnes, si une exception se produirait.

Ce que je voudrais faire est donc: utilisez effectivement la capacité de mise à jour de schéma d’Hibernate Tools, mais vous devez également ajouter à cela quelques rappels de maintenance de schéma et de données, 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 des 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 effectuée. Là où plus de complexité est nécessaire, plus de travail sera nécessaire.

Cela suppose que l'application, une fois mise à jour, est 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top