Jakie są możliwe wartości konfiguracji Hibernacja hbm2ddl.auto i co robią

1084

Naprawdę chcę wiedzieć więcej o aktualizacji, eksporcie i wartościach, które można podać. hibernate.hbm2ddl.auto
Muszę wiedzieć, kiedy korzystać z aktualizacji, a kiedy nie? A jaka jest alternatywa?

Oto zmiany, które mogą wystąpić w DB:

  • nowe stoły
  • nowe kolumny w starych tabelach
  • kolumny usunięte
  • zmieniono typ danych kolumny
  • typ kolumny zmienił swoje atrybuty
  • spadły stoły
  • zmieniono wartości kolumny

W każdym przypadku jakie jest najlepsze rozwiązanie?

Vlad Mihalcea
źródło

Odpowiedzi:

1082

Z dokumentacji społeczności :

hibernate.hbm2ddl.auto Automatycznie sprawdza poprawność lub eksportuje schemat DDL do bazy danych podczas tworzenia SessionFactory. W przypadku utworzenia i upuszczenia schemat bazy danych zostanie usunięty, gdy SessionFactory zostanie jawnie zamknięty.

np. zatwierdzić | aktualizacja | utwórz | Utwórz-upuść

Lista możliwych opcji to:

  • sprawdzanie poprawności : sprawdzanie poprawności schematu, brak zmian w bazie danych.
  • aktualizacja : zaktualizuj schemat.
  • create : tworzy schemat, niszcząc poprzednie dane.
  • create-drop : upuść schemat, gdy SessionFactory zostanie jawnie zamknięte, zwykle po zatrzymaniu aplikacji.
  • none : nic nie robi ze schematem, nie wprowadza żadnych zmian w bazie danych

Wydaje się, że te opcje są narzędziami programistycznymi i nie ułatwiają baz danych na poziomie produkcyjnym, możesz rzucić okiem na następujące pytanie; Hibernacja: hbm2ddl.auto = aktualizacja w produkcji?

James McMahon
źródło
14
Po prostu przeczytaj hibernację docu ... dla prawidłowych wartości, powie: „np.” ... czy są jakieś inne prawidłowe wartości?
Ta Sas,
16
Myślę, że mówi „np.”, Ponieważ jest to tylko dokumentacja społeczności, jeśli ktoś jest zainteresowany wszystkimi możliwymi wartościami, można go znaleźć w javadoc Hibernata. (I tak, tylko te cztery opcje są obecne) docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/cfg/…
szegedi
4
sprawdzanie poprawności mówi sprawdzanie poprawności schematu, co to dokładnie znaczy?
Hussain Akhtar Wahid „Ghouri”
6
Możesz również użyć „aardvark”, „gołąb” lub dowolnego innego słowa, jeśli chcesz, aby hibernacja nic nie robiła. Oczywiście nie polecam tego!
Ward
2
Mały dodatek do opcji tworzenia i upuszczania. Jeśli ta opcja jest użyta, nie usuwa całego schematu, a zamiast tego upuszcza tabele, których odwzorowania są dostępne podczas uruchamiania tego. Na przykład, jeśli baza danych ze schematem S ma tabele A, B, C, a kod Java ma odwzorowania tylko dla A i B, wówczas Hibernacja nie upuści tabeli C.
Aditya
194

Istnieje również nieudokumentowana wartość „none”, która całkowicie ją wyłącza.

Michiel Verkaik
źródło
7
Jest to w rzeczywistości całkiem przydatne, ponieważ sprawdzanie poprawności schematu Hibernacji czasami kończy się niepowodzeniem w przypadku idealnie prawidłowych schematów.
Michael Piefel,
Właśnie miałem prosić o coś takiego. Moim zamiarem jest skrócenie czasu uruchamiania.
digao_mb,
46
„pusty ciąg” jest lepszy niż „brak” . Aby użyć „none”, pojawi się komunikat ostrzegawczy: org.hibernate.cfg.SettingsFactory - Nierozpoznana wartość dla „hibernate.hbm2ddl.auto”: none
okwap
14
Załatałem to. Dodano „none” jako jawnie poprawną stałą.
Sanne
9
Lubię „hibernacja.hbm2ddl.auto = ziemniak” nad innymi stackoverflow.com/a/15810379/838444
Sneg
161

Wywoływana jest właściwość konfiguracji hibernate.hbm2ddl.auto

W naszym środowisku programistycznym postanowiliśmy hibernate.hbm2ddl.auto=create-dropporzucić i utworzyć czystą bazę danych przy każdym wdrożeniu, aby nasza baza danych była w znanym stanie.

Teoretycznie możesz ustawić hibernate.hbm2ddl.auto=updateaktualizację bazy danych za pomocą zmian w modelu, ale nie ufałbym temu w produkcyjnej bazie danych. Wcześniejsza wersja dokumentacji mówiła, że ​​przynajmniej eksperymentalna; Nie znam obecnego stanu.

Dlatego w przypadku naszej produkcyjnej bazy danych nie należy ustawiać hibernate.hbm2ddl.auto- domyślnie nie wprowadza się żadnych zmian w bazie danych. Zamiast tego tworzymy ręcznie skrypt aktualizacji SQL DDL, który stosuje zmiany z jednej wersji do drugiej.

Peter Hilton
źródło
5
W rzeczywistości, zgodnie z dokumentacją, create-drop tworzy tabele bazy danych i upuszcza je, gdy fabryka sesji jest jawnie zamknięta. To nie nie upuścić tabele gdy fabryka sesja jest tworzony.
Frans
4
Nie, zarówno create-drop, jak i create upuszczają tabele, gdy tworzony jest sessionfactory, a następnie create-drop upuszcza tabele również, gdy jest zamknięty sessionfactory. Zobacz stackoverflow.com/a/6752698/1536382
Testo Testini
czy zrobienie hibernacji.hbm2ddl.auto = tworzenie-spadek produkcji może prowadzić do kilku limitów czasu połączenia w produkcji?
METTAIBI
51

Użyłbym liquibase za aktualizowanie db. Funkcja aktualizacji schematu hibernacji jest naprawdę odpowiednia tylko dla programistów, którzy opracowują nowe funkcje. W sytuacji produkcyjnej aktualizacja db musi być traktowana ostrożniej.

Poklepać
źródło
6
Zobacz stackoverflow.com/questions/221379/ ..., dlaczego nie powinieneś używać hbm2ddl do produkcji.
Nathan Voxland,
51

Chociaż jest to dość stary post, ale ponieważ przeprowadziłem kilka badań na ten temat, pomyślałem o udostępnieniu go.

hibernate.hbm2ddl.auto

Zgodnie z dokumentacją może mieć cztery prawidłowe wartości:

utwórz | aktualizacja | zatwierdzić | Utwórz-upuść

Poniżej wyjaśniono zachowanie pokazane przez te wartości:

  • create : - utwórz schemat, dane poprzednio obecne (jeśli istnieją) w schemacie zostaną utracone
  • aktualizacja: - zaktualizuj schemat o podane wartości.
  • sprawdzanie poprawności: - sprawdzanie poprawności schematu. Nie wprowadza żadnych zmian w DB.
  • create-drop: - utwórz schemat, niszcząc poprzednio obecne dane (jeśli istnieją). Upuszcza również schemat bazy danych, gdy SessionFactory jest zamknięty.

Oto ważne punkty, na które warto zwrócić uwagę:

  • W przypadku aktualizacji , jeśli schemat nie jest obecny w bazie danych, wówczas schemat jest tworzony.
  • W przypadku sprawdzania poprawności , jeśli schemat nie istnieje w DB, nie jest tworzony. Zamiast tego wygeneruje błąd: -Table not found:<table name>
  • W przypadku tworzenia i upuszczania schemat nie jest usuwany po zamknięciu sesji. Opada tylko po zamknięciu SessionFactory.
  • W przypadku, gdy dam dowolną wartość tej właściwości (powiedzmy abc, zamiast czterech wyżej omówionych wartości) lub pozostanie ona pusta. Pokazuje następujące zachowanie:

    -Jeśli schemat nie występuje w bazie danych: - Tworzy schemat

    -Jeśli schemat znajduje się w bazie danych: - zaktualizuj schemat.

amit
źródło
W rzeczy samej bardzo ważny jest fakt, że schemat zostanie utworzony, jeśli nie istnieje, gdy używana jest „aktualizacja”.
yuranos
tworzenie-upuszczanie jest sprzeczne przy porównywaniu instrukcji „Wyjaśnienie zachowania” i „Ważne punkty”.
VNT,
2
Jaka jest różnica między aktualizacją a pustym ?
yashjain12yj
46

Po pierwsze, możliwe wartości hbm2ddlwłaściwości konfiguracji są następujące:

  • none- Żadna akcja nie jest wykonywana. Schemat nie zostanie wygenerowany.
  • create-only - Zostanie wygenerowany schemat bazy danych.
  • drop - Schemat bazy danych zostanie usunięty i utworzony później.
  • create - Schemat bazy danych zostanie usunięty i utworzony później.
  • create-drop- Schemat bazy danych zostanie usunięty i utworzony później. Po zamknięciu SessionFactoryschemat bazy danych zostanie usunięty.
  • validate - Schemat bazy danych zostanie zweryfikowany przy użyciu odwzorowań encji.
  • update - Schemat bazy danych zostanie zaktualizowany poprzez porównanie istniejącego schematu bazy danych z odwzorowaniami encji.

Poświęciłem wpis na blogu dotyczący najpopularniejszych strategii generowania Hibernacji DDL :

  1. Jest hibernate.hbm2ddl.auto="update"to wygodne, ale mniej elastyczne, jeśli planujesz dodawać funkcje lub wykonywać niestandardowe skrypty.
  2. Najbardziej elastyczne podejście jest użycie Flyway .

Jednak nawet jeśli korzystasz z Flyway, nadal możesz wygenerować skrypt początkowej migracji za pomocą hbm2ddl. W tym artykule pokazano, jak połączyć model jednostki JPA z modelem tabeli jOOQ.

Vlad Mihalcea
źródło
27

hibernate.hbm2ddl.auto automatycznie sprawdza poprawność i eksportuje DDL do schematu podczas tworzenia sessionFactory.

Domyślnie nie wykonuje automatycznie tworzenia ani modyfikacji DB. Jeśli użytkownik ustawi jedną z poniższych wartości, automatycznie zmienia schemat DDL.

  • create - tworzenie tworzenia schematu

    <entry key="hibernate.hbm2ddl.auto" value="create">
  • aktualizacja - aktualizacja istniejącego schematu

    <entry key="hibernate.hbm2ddl.auto" value="update">
  • sprawdzanie poprawności - sprawdzanie poprawności istniejącego schematu

    <entry key="hibernate.hbm2ddl.auto" value="validate">
  • create-drop - twórz i upuszczaj schemat automatycznie po rozpoczęciu i zakończeniu sesji

    <entry key="hibernate.hbm2ddl.auto" value="create-drop">
Vinod Kumawat
źródło
2
co z <entry key = "hibernate.hbm2ddl.auto" value = "none">?
VNT,
17

Jeśli nie chcesz używać ciągów w swojej aplikacji i szukasz predefiniowanych stałych, spójrz na org.hibernate.cfg.AvailableSettingsklasę zawartą w Hibernacyjnym pliku JAR, gdzie znajdziesz stałą dla wszystkich możliwych ustawień. W twoim przypadku na przykład:

/**
 * 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";
Stefan Haberl
źródło
5
Dlaczego odniesienie do ponad 700-liniowego pliku źródłowego powyżej prostej odpowiedzi z prawie 500 powiększeniami?
Pavel Niedoba
... to pytanie nie ma sensu. Dlaczego są takie rzeczy? Dlaczego w ogóle tu jestem?
specializt
8
  • validate: sprawdza poprawność schematu, baza danych nie zmienia się.
  • update: aktualizuje schemat przy użyciu bieżącego zapytania.
  • create: za każdym razem tworzy nowy schemat i niszczy poprzednie dane.
  • create-drop: upuszcza schemat po zatrzymaniu aplikacji lub jawnym zamknięciu SessionFactory.
Vishal Thakur
źródło
Co to jest „oficjalna” dokumentacja? - tylko się zastanawiam ...
Dirk Schumacher
7

Myślę, że powinieneś się skoncentrować na

SchemaExport Class 

ta klasa sprawia, że ​​Twoja konfiguracja jest dynamiczna, dzięki czemu możesz wybrać to, co najbardziej ci odpowiada ...

Zamówienie [SchemaExport]

Vishal Sharma
źródło
4

validate: Sprawdza poprawność schematu i nie wprowadza żadnych zmian w bazie danych.
Załóżmy, że dodałeś nową kolumnę do pliku odwzorowania i wykonasz operację wstawiania, spowoduje to zgłoszenie wyjątku „brak kolumny XYZ”, ponieważ istniejący schemat jest inny niż obiekt, który zamierzasz wstawić. Jeśli zmienisz tabelę, dodając ręcznie tę nową kolumnę, a następnie wykonaj operację Wstaw, to z pewnością wstawi wszystkie kolumny wraz z nową kolumną do tabeli. Oznacza, że ​​nie wprowadza żadnych zmian / zmienia istniejący schemat / tabelę.

update: zmienia istniejącą tabelę w bazie danych podczas wykonywania operacji. Możesz dodawać lub usuwać kolumny za pomocą tej opcji hbm2ddl. Ale jeśli zamierzasz dodać nową kolumnę, która nie ma wartości „NULL”, to zignoruje dodanie tej konkretnej kolumny do bazy danych. Ponieważ tabela musi być pusta, jeśli chcesz dodać kolumnę „NOT NULL” do istniejącej tabeli.

Arun Raaj
źródło
3

Od wersji 5.0 można teraz znaleźć te wartości w dedykowanym Enum: org.hibernate.boot.SchemaAutoTooling(wzbogaconym o wartość NONEod 5.2).

Lub nawet lepiej, ponieważ 5.1 , możesz również użyć tego, który łączy JPA 2 i „starsze” działania Hibernacji DDL.org.hibernate.tool.schema.Action Enum

Ale nie można jeszcze skonfigurować tego DataSourceprogramowo. Byłoby lepiej użyć tego w połączeniu z, org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTOale obecny kod oczekuje Stringwartości (fragment zaczerpnięty z SessionFactoryBuilderImpl):

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

… Oraz wewnętrzne enumwartości obu tych elementów org.hibernate.boot.SchemaAutoToolingi org.hibernate.tool.schema.Actionnie są ujawniane publicznie.

Poniżej przykładowa DataSourcekonfiguracja programowa (używana w moich aplikacjach Spring Boot), która wykorzystuje gambit dzięki, .name().toLowerCase()ale działa tylko z wartościami bez myślnika (nie create-dropna przykład):

@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();
}
Doc Davluz
źródło
0

Do kogo szuka wartości domyślnej ...

Jest napisany w kodzie źródłowym w wersji 2.0.5 Spring-boot i 1.1.0 w 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;
ibrahim demir
źródło