Domanda

Va ??bene eseguire applicazioni Hibernate configurate con hbm2ddl.auto = update per aggiornare lo schema del database in un ambiente di produzione?

È stato utile?

Soluzione

No, non è sicuro.

Nonostante i migliori sforzi del team di Hibernate, semplicemente non puoi fare affidamento sugli aggiornamenti automatici in produzione . Scrivi le tue patch, esaminale con DBA, testale, quindi applicale manualmente.

Teoricamente, se aggiornamento hbm2ddl ha funzionato nello sviluppo, dovrebbe funzionare anche nella produzione. Ma in realtà non è sempre così.

Anche se ha funzionato bene, potrebbe non essere ottimale. I DBA vengono pagati così tanto per un motivo.

Altri suggerimenti

Lo facciamo in produzione anche se con un'applicazione non mission-critical e senza DBA altamente retribuiti per il personale. È solo un processo manuale in meno soggetto a errore umano: l'applicazione è in grado di rilevare la differenza e fare la cosa giusta, inoltre presumibilmente l'hai testata in vari ambienti di sviluppo e test.

Un avvertimento: in un ambiente di cluster potresti volerlo evitare perché più app possono essere visualizzate contemporaneamente e provare a modificare lo schema che potrebbe essere negativo. O inserire un meccanismo in cui solo un'istanza è autorizzata ad aggiornare lo schema.

I creatori di Hibernate scoraggiano farlo in un ambiente di produzione nel loro libro " Persistenza Java con Hibernate " :

  

ATTENZIONE: abbiamo visto gli utenti di Hibernate tentare di utilizzare SchemaUpdate per aggiornare automaticamente lo schema di un database di produzione. Questo può rapidamente finire in un disastro e non sarà consentito dal tuo DBA.

Dai un'occhiata a LiquiBase XML per conservare un registro degli aggiornamenti. Non l'avevo mai usato fino a quest'anno, ma ho scoperto che è molto facile da imparare e rendere il controllo della revisione del DB / migrazione / gestione delle modifiche molto infallibile. Lavoro a un progetto Groovy / Grails e Grails usa Hibernate per tutto il suo ORM (chiamato "GORM"). Utilizziamo Liquibase per gestire tutte le modifiche allo schema SQL, cosa che facciamo abbastanza spesso man mano che la nostra app si evolve con nuove funzionalità.

Fondamentalmente, mantieni un file XML di changeset che continui ad aggiungere man mano che la tua applicazione evolve. Questo file è tenuto in git (o qualunque cosa tu stia usando) con il resto del tuo progetto. Quando la tua app viene distribuita, Liquibase controlla la sua tabella dei log nel DB a cui ti stai connettendo in modo che sappia cosa è già stato applicato, quindi applica in modo intelligente qualsiasi modifica che non sia stata ancora applicata dal file. In pratica funziona assolutamente alla grande e se lo usi per tutte le modifiche allo schema, puoi essere sicuro al 100% che il codice che esegui il checkout e la distribuzione sarà sempre in grado di connettersi a uno schema di database pienamente compatibile.

La cosa fantastica è che posso prendere un database mysql di ardesia totalmente vuoto sul mio laptop, accendere l'app e subito lo schema è impostato per me. Inoltre, semplifica il test delle modifiche allo schema applicandole prima a uno sviluppatore locale o mettendo in scena db.

Il modo più semplice per iniziare sarebbe probabilmente quello di prendere il tuo DB esistente e quindi usare Liquibase per generare un file iniziale baseline.xml. Quindi in futuro puoi semplicemente aggiungerlo e lasciare che liquibase assuma la gestione delle modifiche allo schema.

http://www.liquibase.org/

Hibernate deve mettere la dichiarazione di non responsabilità sul non utilizzare gli aggiornamenti automatici in prod per coprirsi quando le persone che non sanno cosa stanno facendo lo usano in situazioni in cui non dovrebbe essere usato.

Concesso le situazioni in cui non dovrebbe essere usato molto più di quelle in cui è OK.

L'ho usato per anni in molti progetti diversi e non ho mai avuto un singolo problema. Questa non è una risposta scadente, e non è la codifica da cowboy. È un fatto storico.

Una persona che dice "non farlo mai in produzione" sta pensando a una serie specifica di implementazioni produttive, vale a dire quelle con cui ha familiarità (la sua azienda, la sua industria, ecc.).

L'universo di " implementazioni di produzione " è vasto e vario.

Uno sviluppatore Hibernate con esperienza sa esattamente quale sarà il risultato DDL da una data configurazione di mappatura. Finché testerai e confermerai che ciò che ti aspetti finisce nel DDL (in sviluppo, qa, messa in scena, ecc.), Stai bene.

Quando aggiungi molte funzionalità, gli aggiornamenti automatici dello schema possono farti risparmiare tempo reale.

L'elenco delle cose che gli aggiornamenti automatici non gestiranno è infinito, ma alcuni esempi sono la migrazione dei dati, l'aggiunta di colonne non annullabili, la modifica dei nomi delle colonne, ecc. ecc.

Inoltre devi prenderti cura degli ambienti cluster.

Ma ancora una volta, se tu sapessi tutte queste cose, non faresti questa domanda. Hmm . . OK, se stai ponendo questa domanda, dovresti aspettare fino a quando non avrai molta esperienza con Hibernate e gli aggiornamenti dello schema automatico prima di pensare di usarlo in prod.

Vorrei votare no. Hibernate non sembra capire quando i tipi di dati per le colonne sono cambiati. Esempi (usando 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

Probabilmente ci sono anche altri esempi, come spingere la lunghezza di una colonna String su 255 e vederla convertire in testo, medio testo, ecc.

Concesso, non credo che ci sia davvero un modo per " convertire i tipi di dati " con senza creare una nuova colonna, copiando i dati e spazzando via la vecchia colonna. Ma nel momento in cui il tuo database ha colonne che non riflettono l'attuale mappatura di Hibernate, stai vivendo molto pericolosamente ...

Flyway è una buona opzione per affrontare questo problema:

http://flywaydb.org

Come ho spiegato in questo articolo , non è una buona idea usa hbm2ddl.auto in produzione.

L'unico modo per gestire lo schema del database è utilizzare gli script di migrazione incrementale perché:

  • gli script risiederanno in VCS lungo la tua base di codice. Quando esegui il checkout di un ramo, ricrea l'intero schema da zero.
  • gli script incrementali possono essere testati su un server QA prima di essere applicati in produzione
  • non è necessario alcun intervento manuale poiché gli script possono essere eseguiti da Flyway , quindi riduce la possibilità di errore associato all'esecuzione manuale degli script.

Anche la Hibernate Guida dell'utente consiglia di evitare di utilizzare lo strumento hbm2ddl per ambienti di produzione.

 inserisci qui la descrizione dell

Non rischierei perché potresti perdere dati che avrebbero dovuto essere conservati. hbm2ddl.auto = update è puramente un modo semplice per mantenere aggiornato il database degli sviluppatori.

Lo facciamo in un progetto in esecuzione da mesi ormai e non abbiamo mai avuto problemi finora. Tieni presente i 2 ingredienti necessari per questa ricetta:

  1. Progetta il tuo modello a oggetti con un approccio di retrocompatibilità, ovvero deprecare oggetti e attributi anziché rimuoverli / alterarli. Ciò significa che se è necessario modificare il nome di un oggetto o di un attributo, lasciare quello vecchio così com'è, aggiungere quello nuovo e scrivere una sorta di script di migrazione. Se hai bisogno di cambiare un'associazione tra oggetti, se sei già in produzione, questo significa che il tuo design era sbagliato in primo luogo, quindi prova a pensare a un nuovo modo di esprimere la nuova relazione, senza influire sui vecchi dati.

  2. Sempre esegui il backup del database prima della distribuzione.

Il mio senso è - dopo aver letto questo post - che il 90% delle persone che prendono parte a questa discussione sono inorriditi solo dal pensiero di usare automazioni come questa in un ambiente di produzione. Alcuni lanciano la palla al DBA. Prenditi un momento per considerare che non tutti gli ambienti di produzione forniranno un DBA e non molti team di sviluppatori sono in grado di permettersene uno (almeno per progetti di medie dimensioni). Quindi, se stiamo parlando di squadre in cui tutti devono fare tutto, la palla è su di loro.

In questo caso, perché non provare ad avere il meglio dei due mondi? Strumenti come questo sono qui per dare una mano, che - con una progettazione e un piano accurati - può aiutare in molte situazioni. E credetemi, inizialmente gli amministratori potrebbero essere difficili da convincere, ma se sanno che la palla non è nelle loro mani, lo adoreranno.

Personalmente, non tornerei mai più a scrivere script a mano per estendere qualsiasi tipo di schema, ma questa è solo la mia opinione. E dopo aver iniziato ad adottare database NoSQL senza schema di recente, posso vedere che più che presto, tutte queste operazioni basate su schemi apparterranno al passato, quindi è meglio iniziare a cambiare prospettiva e guardare avanti.

  • Nel mio caso (Hibernate 3.5.2, Postgresql, Ubuntu), l'impostazione hibernate.hbm2ddl.auto = update ha creato solo nuove tabelle e creato nuove colonne in tabelle già esistenti.

  • Non ha eliminato né le tabelle né le colonne, né ha modificato le colonne. Può essere definita un'opzione sicura, ma qualcosa come hibernate.hbm2ddl.auto = create_tables add_columns sarebbe più chiaro.

Non è sicuro, non raccomandato, ma è possibile.

Ho esperienza in un'applicazione che utilizza l'opzione di aggiornamento automatico in produzione.

Bene, i principali problemi e rischi riscontrati in questa soluzione sono:

  • Distribuisci nel database errato . Se commetti l'errore di eseguire il server delle applicazioni con una versione precedente dell'applicazione (EAR / WAR / etc) nel database errato ... Avrai un sacco di nuove colonne, tabelle, chiavi esterne ed errori. Lo stesso problema può verificarsi con un semplice errore nel file dell'origine dati (copia / incolla file e dimentica di cambiare il database). In conclusione, la situazione può essere un disastro nel database.
  • Il server delle applicazioni impiega troppo tempo ad avviarsi . Ciò si verifica perché l'ibernazione tenta di trovare tutte le tabelle / colonne / etc create ogni volta che si avvia l'applicazione. Deve sapere cosa deve essere creato (tabella, colonna, ecc.). Questo problema peggiorerà man mano che crescono le tabelle del database.
  • Strumenti di database è quasi impossibile da usare . Per creare script di database da eseguire con una nuova versione, è necessario pensare a ciò che verrà creato dall'aggiornamento automatico dopo aver avviato il server delle applicazioni. Ad esempio, se è necessario riempire una nuova colonna con alcuni dati, è necessario avviare il server delle applicazioni, attendere l'ibernazione per cancellare la nuova colonna ed eseguire lo script SQL solo dopo. Come puoi vedere, gli strumenti di migrazione del database (come Flyway, Liquibase, ecc.) Sono quasi impossibili da usare con l'aggiornamento automatico abilitato.
  • Le modifiche al database non sono centralizzate . Con la possibilità di Hibernate di creare le tabelle e tutto il resto, è difficile guardare le modifiche sul database in ogni versione dell'applicazione, poiché la maggior parte di esse è automaticamente.
  • Incoraggia la spazzatura nel database . A causa della facilità di aggiornamento automatico, è possibile che il tuo team trascuri di eliminare vecchie colonne e vecchie tabelle.
  • Disastro imminente . L'imminente rischio che si verifichi un disastro nella produzione (come alcune persone citate in altre risposte). Anche con un'applicazione in esecuzione e aggiornabile per anni, non credo sia sicuro. Non mi sono mai sentito al sicuro con questa opzione attivata.

Quindi, non consiglierò di utilizzare l'aggiornamento automatico in produzione.

Se si desidera veramente utilizzare l'aggiornamento automatico in produzione, si consiglia:

  • Reti separate . Il tuo ambiente di test non può accedere all'ambiente omologa. Ciò consente di impedire che una distribuzione che si suppone si trovi nell'ambiente di test cambi il database di omologazione.
  • Gestisci ordine script . È necessario organizzare gli script da eseguire prima della distribuzione (modifica della tabella della struttura, eliminazione della tabella / colonne) e script dopo la distribuzione (compilare le informazioni per le nuove colonne / tabelle).

E, a differenza degli altri post, non credo che l'aggiornamento automatico abbia permesso di essere collegato con "molto ben pagato" DBA (come menzionato in altri post) ... I DBA hanno cose più importanti da fare che scrivere istruzioni SQL per creare / modificare / eliminare tabelle e colonne. Queste semplici attività quotidiane possono essere eseguite e automatizzate dagli sviluppatori e passate solo al team DBA per la revisione, senza la necessità di Hibernate e DBA "molto ben pagate". per scriverli.

No, non farlo mai. Hibernate non gestisce la migrazione dei dati. Sì, farà apparire correttamente il tuo schema ma non garantisce che dati di produzione preziosi non vengano persi nel processo.

  • In genere le applicazioni aziendali in organizzazioni di grandi dimensioni vengono eseguite con privilegi ridotti.

  • Il nome utente del database potrebbe non avere il privilegio DDL per l'aggiunta di colonne che hbm2ddl.auto = update richiede.

Sono d'accordo con Vladimir. Gli amministratori della mia azienda non apprezzerebbero sicuramente se avessi persino suggerito un corso del genere.

Inoltre, la creazione di uno script SQL al posto della fiducia cieca di Hibernate ti dà l'opportunità di rimuovere i campi che non sono più in uso. Hibernate non lo fa.

E trovo che il confronto dello schema di produzione con il nuovo schema ti offra una visione ancora migliore di ciò che hai modificato nel modello di dati. Sai, ovviamente, perché ce l'hai fatta, ma ora vedi tutti i cambiamenti in una volta sola. Anche quelli che ti fanno andare come " What the diamine?! & Quot ;.

Esistono strumenti che possono creare un delta dello schema per te, quindi non è nemmeno un duro lavoro. E poi sai esattamente cosa succederà.

Lo schema delle applicazioni potrebbe evolversi nel tempo; se si dispone di più installazioni, che possono trovarsi in versioni diverse, è necessario disporre di un modo per garantire che l'applicazione, un tipo di strumento o script sia in grado di migrare schemi e dati da una versione in modo graduale a quella successiva.

Avere tutta la tua persistenza nelle mappature (o annotazioni) di Hibernate è un ottimo modo per tenere sotto controllo l'evoluzione dello schema.

Dovresti considerare che l'evoluzione dello schema ha diversi aspetti da considerare:

  1. evoluzione dello schema del database in aggiungendo più colonne e tabelle

  2. eliminazione di vecchie colonne, tabelle e rapporti

  3. riempiendo le nuove colonne di default

Gli strumenti di ibernazione sono importanti in particolare nel caso (come nella mia esperienza) hai versioni diverse della stessa applicazione su molti tipi diversi di database.

Il punto 3 è molto sensibile nel caso in cui si stia utilizzando Hibernate, come nel caso in cui si introduca una nuova proprietà con valore booleano o numerica, se Hibernate troverà un valore nullo in tali colonne, se solleverà un'eccezione.

Quindi quello che vorrei fare è: utilizzare davvero la capacità degli strumenti di Hibernate di aggiornamento dello schema, ma è necessario aggiungere al suo interno alcuni callback di manutenzione dei dati e dello schema, come per riempire i valori predefiniti, eliminare colonne non più utilizzate e simili. In questo modo si ottengono i vantaggi (script di aggiornamento dello schema indipendenti dal database ed evitando la duplicazione della codifica degli aggiornamenti, in peristenza e in script) ma si coprono anche tutti gli aspetti dell'operazione.

Quindi, ad esempio, se un aggiornamento di versione consiste semplicemente nell'aggiungere una proprietà con valore varchar (quindi colonna), che può essere impostata su null per impostazione predefinita, con l'aggiornamento automatico verrà eseguito. Laddove è necessaria una maggiore complessità, sarà necessario più lavoro.

Questo presuppone che l'applicazione, una volta aggiornata, sia in grado di aggiornare il suo schema (può essere fatto), il che significa anche che deve avere i diritti utente per farlo sullo schema. Se la politica del cliente lo impedisce (probabile caso Lizard Brain), dovrai fornire gli script specifici del database.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top