java - generation - hibernate.hbm2ddl.auto default




Hibernate hbm2ddl.auto valori possibili e cosa fanno? (9)

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

Queste sono modifiche che potrebbero accadere su DB:

  • nuovi tavoli
  • nuove colonne in vecchie tabelle
  • colonne cancellate
  • tipo di dati di una colonna modificata
  • 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?


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

hibernate.hbm2ddl.auto

Come da documentazione può avere quattro valori validi:

creare | aggiornamento | convalidare | creare-drop

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

  • creare : - creare lo schema, i dati precedentemente presenti (se presenti) nello schema sono persi
  • aggiornamento: - aggiorna lo schema con i valori dati.
  • convalidare: - convalidare lo schema. Non cambia nel DB.
  • create-drop: - crea lo schema con la distruzione dei dati precedentemente presenti (se presenti). Elimina anche lo schema del database quando SessionFactory viene chiuso.

Di seguito sono riportati i punti importanti che vale la pena 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 eliminato alla chiusura della sessione. Si abbassa solo alla chiusura di SessionFactory.
  • Nel caso in cui io dia alcun valore a questa proprietà (ad esempio, abc, invece di sopra quattro valori discussi sopra) o è appena lasciato in bianco. Mostra il seguente comportamento:

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

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


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


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

  1. hibernate.hbm2ddl.auto="update" è comodo ma meno flessibile se si intende aggiungere funzioni o eseguire script personalizzati.
  2. L' approccio più flessibile è l'utilizzo di 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.


In teoria, puoi impostare hibernate.hbm2ddl.auto = update per aggiornare il tuo database con le modifiche al tuo modello, ma non mi fiderei di ciò su un database di produzione. Una versione precedente della documentazione diceva che questo era sperimentale, almeno; 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.


Penso che dovresti concentrarti sul

SchemaExport Class 

questa classe rende dinamica la tua configurazione Quindi ti permette di scegliere le suite che preferisci ...

Cassa [SchemaExport]


Se non vuoi utilizzare le stringhe nella tua app e stai cercando costanti predefinite, consulta la classe org.hibernate.cfg.AvailableSettings inclusa nel JAR di Hibernate, dove troverai una costante per tutte le impostazioni possibili. Nel tuo caso per 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";

Userò liquibase per aggiornare il tuo db. la funzionalità di aggiornamento dello schema di hibernate è in realtà accettabile solo per uno sviluppatore mentre sta sviluppando nuove funzionalità. In una situazione di produzione, l'aggiornamento db deve essere gestito con maggiore attenzione.


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

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

  • crea - facendo la creazione di uno schema

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

    <entry key="hibernate.hbm2ddl.auto" value="update">
    
  • convalida - 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">
    

Dalla 5.0 , è ora possibile trovare quei valori in un Enum dedicato: org.hibernate.boot.SchemaAutoTooling (arricchito con valore NONE dal 5.2).

O ancora meglio, dal 5.1 , è anche possibile utilizzare l' org.hibernate.tool.schema.Action Enum che combina le azioni DDL Hibernate di JPA 2 e "legacy".

Ma non è ancora possibile configurare un DataSource programmatico con questo. Sarebbe org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO usarlo in combinazione con org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO ma il codice corrente prevede un valore di String (estratto da SessionFactoryBuilderImpl ):

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

... e valori interni di enum di org.hibernate.boot.SchemaAutoTooling e org.hibernate.tool.schema.Action non sono esposti pubblicamente.

Qui di seguito, un esempio di configurazione programmatica di DataSource (utilizzata in una delle mie applicazioni Spring Boot) che usa una gambit grazie a .name().toLowerCase() ma funziona solo con valori senza dash (non create-drop per 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();
}




hbm2ddl