Quali sono i possibili valori della configurazione di Hibernate hbm2ddl.auto e cosa fanno


1085

Voglio davvero saperne di più sull'aggiornamento, sull'esportazione e sui valori che potrebbero essere forniti. hibernate.hbm2ddl.auto
Devo sapere quando utilizzare l'aggiornamento e quando no? E qual è l'alternativa?

Queste sono le modifiche che potrebbero verificarsi sul DB:

  • nuovi tavoli
  • nuove colonne in vecchie tabelle
  • colonne eliminate
  • il tipo di dati di una colonna è cambiato
  • un tipo di colonna ha cambiato i suoi attributi
  • tavoli caduti
  • i valori di una colonna sono cambiati

In ogni caso qual è la soluzione migliore?

Risposte:


1083

Dalla documentazione della comunità :

hibernate.hbm2ddl.auto Convalida o esporta automaticamente lo schema DDL nel database quando viene creato SessionFactory. Con create-drop, lo schema del database verrà eliminato quando SessionFactory viene chiusa in modo esplicito.

es. validare | aggiornamento | creare | creare-drop

Quindi l'elenco delle possibili opzioni sono,

  • convalida : convalida lo schema, non apporta modifiche al database.
  • aggiornamento : aggiorna lo schema.
  • crea : crea lo schema, distruggendo i dati precedenti.
  • create-drop : elimina lo schema quando SessionFactory viene chiusa in modo esplicito, in genere quando l'applicazione viene arrestata.
  • none : non fa nulla con lo schema, non modifica il database

Queste opzioni sembrano essere strumenti per sviluppatori e non per facilitare alcun database a livello di produzione, potresti voler dare un'occhiata alla seguente domanda; Sospensione: hbm2ddl.auto = aggiornamento in produzione?


14
Basta leggere il documento di ibernazione ... per i valori validi, dice: "es." ... ci sono altri valori validi?
Ta Sas,

16
Penso che dica "ad esempio" perché è solo una documentazione della comunità, se qualcuno è interessato a tutti i possibili valori, può essere trovato nel javadoc di Hibernate. (E sì, sono presenti solo queste quattro opzioni) docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/cfg/…
szegedi,

4
validate dice validate lo schema, cosa significa esattamente ??
Hussain Akhtar Wahid 'Ghouri',

6
Puoi anche usare "aardvark", "piccione" o qualsiasi altra parola, se vuoi che l'ibernazione non faccia nulla. Non che lo consiglierei ovviamente!
Ward,

2
Una piccola aggiunta all'opzione create-drop. Se questa opzione viene utilizzata, non elimina l'intero schema, ma elimina le tabelle i cui mapping sono disponibili durante l'esecuzione. Ad esempio se un database con Schema S ha tabelle A, B, C e il codice java ha mappature solo per A e B, Hibernate non eliminerà la tabella C.
Aditya,

194

C'è anche il valore non documentato di "none" per disabilitarlo del tutto.


7
Questo è in realtà abbastanza utile poiché la convalida dello schema di Hibernate a volte fallisce per schemi perfettamente validi.
Michael Piefel,

Stavo per chiedere qualcosa del genere. La mia intenzione è di ridurre i tempi di avvio.
digao_mb,

46
'stringa vuota' è meglio di 'nessuna' . Per usare 'none', riceverai un messaggio di avviso: org.hibernate.cfg.SettingsFactory - Valore non riconosciuto per "hibernate.hbm2ddl.auto": none
okwap

14
L'ho patchato. Aggiunto "nessuno" come costante esplicitamente valida.
Sanne,

9
Mi piace "hibernate.hbm2ddl.auto = potato" rispetto ad altri stackoverflow.com/a/15810379/838444
Sneg

161

Viene chiamata la proprietà di configurazione hibernate.hbm2ddl.auto

Nel nostro ambiente di sviluppo decidiamo hibernate.hbm2ddl.auto=create-dropdi eliminare e creare un database pulito ogni volta che lo distribuiamo, in modo che il nostro database sia in uno stato noto.

In teoria, puoi impostare hibernate.hbm2ddl.auto=updatel'aggiornamento del tuo database con modifiche al tuo modello, ma non mi fiderei di questo su un database di produzione. Una versione precedente della documentazione diceva che questo era almeno sperimentale; Non conosco lo stato attuale.

Pertanto, per il nostro database di produzione, non impostare hibernate.hbm2ddl.auto: l'impostazione predefinita è di non apportare modifiche al database. Invece, creiamo manualmente uno script di aggiornamento DDL SQL che applica le modifiche da una versione alla successiva.


5
In realtà, secondo la documentazione, create-drop crea le tabelle del database e le rilascia quando la factory di sessione viene esplicitamente chiusa. Essa non eliminare le tabelle quando viene creata la fabbrica di sessione.
Frans,

4
No, sia create-drop che create drop the tables quando viene creata la sessionfactory, quindi create-drop elimina le tabelle anche quando sessionfactory è chiusa. Vedi stackoverflow.com/a/6752698/1536382
Testo Testini

fare hibernate.hbm2ddl.auto = create-drop in produzione può portare a diversi timeout di connessione in produzione?
METTAIBI

51

Vorrei usare liquibase per aggiornare il tuo db. La funzionalità di aggiornamento dello schema di hibernate è davvero valida solo per uno sviluppatore mentre stanno sviluppando nuove funzionalità. In una situazione di produzione, l'aggiornamento del db deve essere gestito con più attenzione.


6
Vedi stackoverflow.com/questions/221379/… per il motivo per cui non dovresti usare hbm2ddl per la produzione.
Nathan Voxland,

51

Anche se è un post piuttosto vecchio, ma come ho fatto alcune ricerche sull'argomento, ho pensato di condividerlo.

hibernate.hbm2ddl.auto

Secondo la documentazione può avere quattro valori validi:

creare | aggiornamento | convalidare | creare-drop

Di seguito è la spiegazione del comportamento mostrato da questi valori:

  • crea : - crea lo schema, i dati precedentemente presenti (se presenti) nello schema vengono persi
  • aggiornamento: - aggiorna lo schema con i valori indicati.
  • validate: - validate lo schema. Non effettua alcuna modifica nel DB.
  • create-drop: - crea lo schema distruggendo i dati precedentemente presenti (se presenti). Elimina anche lo schema del database quando SessionFactory è chiusa.

Di seguito sono riportati i punti importanti da notare:

  • In caso di aggiornamento , se lo schema non è presente nel DB, viene creato lo schema.
  • In caso di convalida , se lo schema non esiste nel DB, non viene creato. Invece, genererà un errore: -Table not found:<table name>
  • In caso di create-drop , lo schema non viene rilasciato alla chiusura della sessione. Cade solo alla chiusura della SessionFactory.
  • Nel caso in cui do un valore a questa proprietà (diciamo abc, invece di sopra quattro valori discussi sopra) o viene lasciato vuoto. Mostra il seguente comportamento:

    -Se lo schema non è presente nel DB: - Crea lo schema

    -Se lo schema è presente nel DB: - aggiorna lo schema.


È davvero un punto molto importante che lo schema verrà creato se non esiste, quando viene utilizzato "aggiornamento".
yuranos,

create-drop è contraddetto quando si confrontano le dichiarazioni "Spiegazione del comportamento" e "Punti importanti".
VNT

2
Qual è la differenza tra aggiornamento e vuoto ?
yashjain12yj,

46

Innanzitutto, i possibili valori per la hbm2ddlproprietà di configurazione sono i seguenti:

  • none- Non viene eseguita alcuna azione. Lo schema non verrà generato.
  • create-only - Verrà generato lo schema del database.
  • drop - Lo schema del database verrà eliminato e creato in seguito.
  • create - Lo schema del database verrà eliminato e creato in seguito.
  • create-drop- Lo schema del database verrà eliminato e creato in seguito. Alla chiusura di the SessionFactory, lo schema del database verrà eliminato.
  • validate - Lo schema del database verrà convalidato utilizzando i mapping delle entità.
  • update - Lo schema del database verrà aggiornato confrontando lo schema del database esistente con i mapping delle entità.

Ho dedicato un post sul blog alle più comuni strategie di generazione DDL di Hibernate :

  1. Il hibernate.hbm2ddl.auto="update"è conveniente, ma meno flessibile se avete intenzione di aggiungere funzioni o l'esecuzione di alcuni script personalizzati.
  2. L' approccio più flessibile è utilizzare Flyway .

Tuttavia, anche se si utilizza Flyway, è comunque possibile generare lo script di migrazione iniziale utilizzando hbm2ddl. In questo articolo , puoi vedere come combinare il modello di entità JPA con il modello di tabella jOOQ.


27

hibernate.hbm2ddl.auto convalida automaticamente ed esporta DDL nello schema quando viene creata sessionFactory.

Per impostazione predefinita, non esegue alcuna creazione o modifica automaticamente sul DB. Se l'utente imposta uno dei valori seguenti, sta facendo automaticamente le modifiche allo schema DDL.

  • creare - facendo creando uno schema

    <entry key="hibernate.hbm2ddl.auto" value="create">
  • aggiornamento - aggiornamento dello schema esistente

    <entry key="hibernate.hbm2ddl.auto" value="update">
  • validate - convalida lo schema esistente

    <entry key="hibernate.hbm2ddl.auto" value="validate">
  • create-drop: crea e rilascia lo schema automaticamente all'avvio e alla fine di una sessione

    <entry key="hibernate.hbm2ddl.auto" value="create-drop">

2
che dire di <entry key = "hibernate.hbm2ddl.auto" value = "none">?
VNT

17

Se non vuoi usare le stringhe nella tua app e stai cercando costanti predefinite dai un'occhiata alla org.hibernate.cfg.AvailableSettingsclasse inclusa nel JAR di Hibernate, dove troverai una costante per tutte le possibili impostazioni. Nel tuo caso ad esempio:

/**
 * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
 * <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
 */
String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";

5
Perché il riferimento a più di 700 righe di file di origine sopra una risposta semplice con quasi 500 vole up?
Pavel Niedoba,

... quella domanda non ha alcun senso. Perché ci sono delle cose? Perché sono anche qui?
specializt

8
  • validate: convalida lo schema, nessuna modifica al database.
  • update: aggiorna lo schema con la query di esecuzione corrente.
  • create: crea ogni volta un nuovo schema e distrugge i dati precedenti.
  • create-drop: elimina lo schema quando l'applicazione viene arrestata o SessionFactory viene chiusa esplicitamente.

Qual è il riferimento alla documentazione "ufficiale"? - Mi chiedo solo ...
Dirk Schumacher,

7

Penso che dovresti concentrarti su

SchemaExport Class 

questa classe rende dinamica la tua configurazione Quindi ti consente di scegliere qualsiasi suite tu preferisca ...

Acquista [SchemaExport]


4

validate: Convalida lo schema e non apporta modifiche al DB.
Supponiamo di aver aggiunto una nuova colonna nel file di mapping ed eseguire l'operazione di inserimento, genererà un'eccezione "mancante della colonna XYZ" perché lo schema esistente è diverso dall'oggetto che si intende inserire. Se si modifica la tabella aggiungendo manualmente quella nuova colonna, quindi si esegue l'operazione Inserisci, verranno sicuramente inserite tutte le colonne insieme alla nuova colonna nella tabella. Significa che non apporta alcuna modifica / modifica lo schema / tabella esistente.

update: modifica la tabella esistente nel database quando si esegue l'operazione. È possibile aggiungere o rimuovere colonne con questa opzione di hbm2ddl. Ma se hai intenzione di aggiungere una nuova colonna che è 'NOT NULL', ignorerà l'aggiunta di quella particolare colonna al DB. Perché la tabella deve essere vuota se si desidera aggiungere una colonna "NOT NULL" alla tabella esistente.


3

Da 5.0 , ora puoi trovare quei valori in un dedicato Enum: org.hibernate.boot.SchemaAutoTooling(migliorato con valore NONEda 5.2).

O ancora meglio, dal 5.1 , puoi anche usare la combinazione di azioni JPA 2 e Hibernate DDL "legacy".org.hibernate.tool.schema.Action Enum

Ma non è ancora possibile configurarlo a livello di DataSourceprogrammazione con questo. Sarebbe meglio usarlo insieme a org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTOma il codice corrente prevede un Stringvalore (estratto da SessionFactoryBuilderImpl):

this.schemaAutoTooling = SchemaAutoTooling.interpret( (String) configurationSettings.get( AvailableSettings.HBM2DDL_AUTO ) );

... e i enumvalori interni di entrambi org.hibernate.boot.SchemaAutoToolinge org.hibernate.tool.schema.Actionnon sono esposti pubblicamente.

Di seguito, una DataSourceconfigurazione programmatica di esempio (utilizzata in una delle mie applicazioni Spring Boot) che utilizza un gambetto grazie .name().toLowerCase()ma funziona solo con valori senza trattino (non create-dropper esempio):

@Bean(name = ENTITY_MANAGER_NAME)
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
        EntityManagerFactoryBuilder builder,
        @Qualifier(DATA_SOURCE_NAME) DataSource internalDataSource) {

    Map<String, Object> properties = new HashMap<>();
    properties.put(AvailableSettings.HBM2DDL_AUTO, SchemaAutoTooling.CREATE.name().toLowerCase());
    properties.put(AvailableSettings.DIALECT, H2Dialect.class.getName());

    return builder
            .dataSource(internalDataSource)
            .packages(JpaModelsScanEntry.class, Jsr310JpaConverters.class)
            .persistenceUnit(PERSISTENCE_UNIT_NAME)
            .properties(properties)
            .build();
}

0

A chi cerca il valore predefinito ...

È scritto nel codice sorgente alla versione 2.0.5 di Spring-Boot e 1.1.0 su JpaProperties:

    /**
     * DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto"
     * property. Defaults to "create-drop" when using an embedded database and no
     * schema manager was detected. Otherwise, defaults to "none".
     */
    private String ddlAuto;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.