2013-08-30 13 views
5

Ho un'applicazione in cui Hibernate crea tutti i miei schemi di tabelle ogni volta che l'applicazione viene eseguita su una macchina per la prima volta. Funziona beneCombina la creazione automatica dello schema di Hibernate e il controllo delle versioni del database

Ora ero però chiedendo se Hibernate ha una sorta di meccanismo per mantenere il database sotto controllo di versione, vale a dire si Hibernate sa come migrare uno schema a un altro quando si esegue una versione diversa della mia applicazione e Hibernate trova un database diverso schema da una versione precedente presente? In qualche modo penso che ciò dovrebbe essere possibile, considerando che Hibernate può leggere lo schema esistente e potrebbe confrontare lo schema con la descrizione della mappatura. Tuttavia, non saprei come dire a Hibernate di migrare i vecchi dati come quando si creano script di modifica con ad es. Liquibase/Flyway.

Probabilmente non ho cercato su google le cose giuste poiché Hibernate e il controllo delle versioni ti mostreranno molti successi sul controllo e sul controllo delle versioni, ma sto pensando più in termini di versioni di Liquibase/Flyway. Non ho mai preso in considerazione entrambi, ma poiché Hibernate non crea script di aggiornamento ma manipola direttamente il database, non saprei come far funzionare entrambi.

Questa è la prima volta che Hibernate crea il mio schema invece di scrivere i miei script. Lo faccio per fare uso di Hibernate Envers ciò che rende la creazione di script manuale estremamente noiosa. Forse mi manca qualcosa di ovvio. Grazie per qualsiasi input su questo argomento!

Aggiornamento: Ho avuto modo di parlare con lo sviluppatore di Flyway oggi e mi ha detto che non avrebbe saputo di una buona soluzione. Forse non c'è niente?

+0

Hibernate ha un valore hbm2ddl.auto di "aggiornamento" che proverà a farlo ma non è affidabile. Nella mia esperienza con l'ibernazione, questi aggiornamenti dello schema dovrebbero sempre essere gestiti da script SQL di aggiornamento dello schema scritti manualmente.In genere, l'utente db che l'app sta utilizzando non dovrebbe avere i privilegi di creazione/rilascio, anche se questo potrebbe non essere applicabile nel tuo caso. – Taylor

+0

A mio parere, la scrittura dello schema, alla fine, è una sorta di duplicazione del codice poiché rispecchia similmente un modello di dominio già descritto implementando i miei oggetti Java. Di solito, questa duplicazione non è così costosa, ma con Envers lo è. Quindi vorrei avere una soluzione a questo. In quale contesto hai riscontrato che hbm2dll.auto non è sufficiente. Potrebbe essere un ottimo punto di ingresso per implementare un migratore Flyway personalizzato. –

+0

Quasi ogni contesto. Qualsiasi riorganizzazione di colonne esistenti o qualsiasi modifica diversa da "aggiungi colonna con un singolo valore predefinito" o "rilascia questa colonna" è oltre la capacità di ibernazione da aggiornare. – Taylor

risposta

8

Abbiamo avuto lo stesso problema con il nostro progetto Java/Hibernate e non volevamo uno sforzo di duplicazione del codice. La funzione di "aggiornamento" di Hibernate non è affatto affidabile, LiquidBase è migliore, ma non del tutto infallibile al 100%. Alla fine abbiamo sviluppato un semplice script per gestire il processo seguente:

  1. Lo schema del database "corrente" viene sempre generata da Hibernate, rispetto a un database DEV direttamente.
  2. Uno schema di database "precedente" è generato da una serie di set di modifiche LiquiBase.
  3. Ogni volta che è necessaria una migrazione , una funzione LiquiBase "diff" viene richiamato tra i "precedenti" e le banche dati "correnti" (due basi di dati attuali, sì, in modo più affidabile in questo modo), generando un nuovo set di cambiamento LiquiBase .
  4. Questo set di modifiche deve essere rivisto manualmente. Tutti i set di modifiche sono mantenuti nel controllo del codice sorgente.
  5. Il database PRODUCTION ha lo schema generato applicando tutti i set di modifiche LiquiBase.

un comando chiave nella nostra script legge come il seguente:

${LIQB_COMMAND} ${PREV_DB_OPTIONS} --changeLogFile=${LIQB_CHGLOG_FILE_NEW} \ 
    diffChangeLog \ 
       --referenceUsername=${DEV_DB_USER} \ 
       --referencePassword=${DEV_DB_PWD} \ 
       --referenceDriver=com.mysql.jdbc.Driver \ 
       --referenceUrl=${DEV_DB_URL} 

In questo modo, il nostro processo di migrazione è abbastanza affidabile e non scrivere il codice dello schema due volte. Esiste una revisione manuale del set di modifiche generato in XML, ma la maggior parte delle volte non c'è alcun problema, ed è sicuramente molto più facile della scrittura manuale delle operazioni di modifica dello schema.

+0

Sì. Liquibase è ciò che desideri utilizzare. La funzione di auto-ddl di Hibernate è principalmente uno strumento di sviluppo/test. Sono abbastanza sicuro che questo sia menzionato nella maggior parte dei buoni libri di Hibernate, quindi non sono sicuro del motivo per cui la gente prova ad usare auto-ddl per fare la migrazione dello schema di produzione. –

+0

Perché è conveniente, immagino. Ma pensavo di dover andare verso una soluzione del genere. Non ti è capitato di open source la tua soluzione? –

+0

Sai, in realtà non mi dispiace farlo. È solo che questa parte del codice è incorporata nel nostro progetto. Ci vorrà un po 'di sforzo per pulirlo ulteriormente e renderlo utile a te e agli altri. Fammi sapere per certo che vuoi seguire la rotta e forse puoi aiutare a ripulire il codice per renderlo utile agli altri. – stevel

Problemi correlati