Các giá trị có thể có của cấu hình Hibernate hbm2ddl.auto là gì và chúng làm gì


1085

Tôi thực sự muốn biết thêm về bản cập nhật, xuất và các giá trị có thể được cung cấp cho hibernate.hbm2ddl.auto
tôi cần biết khi nào nên sử dụng bản cập nhật và khi nào thì không? Và thay thế là gì?

Đây là những thay đổi có thể xảy ra trên DB:

  • bảng mới
  • cột mới trong bảng cũ
  • cột đã xóa
  • kiểu dữ liệu của một cột đã thay đổi
  • một loại cột thay đổi thuộc tính của nó
  • bàn rớt
  • giá trị của một cột đã thay đổi

Trong mỗi trường hợp, giải pháp tốt nhất là gì?

Câu trả lời:


1083

Từ tài liệu cộng đồng :

hibernate.hbm2ddl.auto Tự động xác thực hoặc xuất lược đồ DDL sang cơ sở dữ liệu khi SessionFactory được tạo. Với tạo-thả, lược đồ cơ sở dữ liệu sẽ bị loại bỏ khi SessionFactory được đóng rõ ràng.

ví dụ: xác nhận | cập nhật | tạo | tạo ra

Vì vậy, danh sách các tùy chọn có thể là,

  • xác thực : xác thực lược đồ, không thay đổi cơ sở dữ liệu.
  • cập nhật : cập nhật lược đồ.
  • tạo : tạo lược đồ, hủy dữ liệu trước đó.
  • tạo-thả : thả lược đồ khi SessionFactory được đóng rõ ràng, thường là khi ứng dụng bị dừng.
  • none : không làm gì với lược đồ, không thay đổi cơ sở dữ liệu

Các tùy chọn này dường như được dự định là công cụ dành cho nhà phát triển và không tạo điều kiện cho bất kỳ cơ sở dữ liệu cấp sản xuất nào, bạn có thể muốn xem xét câu hỏi sau đây; Hibernate: hbm2ddl.auto = cập nhật trong sản xuất?


14
Chỉ cần đọc tài liệu ngủ đông ... cho các giá trị hợp lệ, nó nói: "ví dụ" ... có bất kỳ giá trị hợp lệ nào khác không?
Ta Sas

16
Tôi nghĩ rằng nó nói "ví dụ" bởi vì nó chỉ là một tài liệu cộng đồng, nếu ai đó quan tâm đến tất cả các giá trị có thể, nó có thể được tìm thấy trong javadoc của Hibernate. (Và vâng, chỉ có bốn tùy chọn đó hiện diện) docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/cfg/ Lỗi
szegedi

4
xác nhận nói xác nhận lược đồ, chính xác nó có nghĩa là gì ??
Hussain Akhtar Wahid 'Ghouri'

6
Bạn cũng có thể sử dụng 'aardvark' hoặc 'pigeon' hoặc bất kỳ từ nào khác, nếu bạn muốn ngủ đông không làm gì cả. Tất nhiên không phải tôi muốn giới thiệu điều đó!
Phường

2
Một bổ sung nhỏ cho tùy chọn tạo thả. Nếu tùy chọn này được sử dụng, nó không bỏ toàn bộ lược đồ thay vào đó nó sẽ loại bỏ các bảng có ánh xạ có sẵn trong khi chạy này. Ví dụ: nếu cơ sở dữ liệu với Schema S có các bảng A, B, C và mã java chỉ có ánh xạ cho A và B thì Hibernate sẽ không bỏ bảng C.
Aditya

194

Ngoài ra còn có giá trị không có giấy tờ của "không" để vô hiệu hóa nó hoàn toàn.


7
Điều này thực sự khá hữu ích vì việc xác thực lược đồ của Hibernate đôi khi không thành công cho các lược đồ hoàn toàn hợp lệ.
Michael Piefel

Tôi chỉ định yêu cầu một cái gì đó như thế này. Ý định của tôi là giảm thời gian khởi động.
digao_mb

46
'chuỗi rỗng' tốt hơn 'không' . Để sử dụng 'none', bạn sẽ nhận được thông báo cảnh báo: org.hibernate.cfg.SinstallFactory - Giá trị không được nhận dạng cho "hibernate.hbm2ddl.auto": none
okwap

14
Tôi đã vá nó. Đã thêm "none" dưới dạng hằng số hợp lệ rõ ràng.
Sanne

9
Tôi thích "hibernate.hbm2ddl.auto = khoai tây" hơn những người khác stackoverflow.com/a/15810379/838444
Sneg 20/07/2016

161

Thuộc tính cấu hình được gọi là hibernate.hbm2ddl.auto

Trong môi trường phát triển của chúng tôi, chúng tôi đã thiết lập hibernate.hbm2ddl.auto=create-dropđể thả và tạo một cơ sở dữ liệu sạch mỗi lần chúng tôi triển khai, để cơ sở dữ liệu của chúng tôi ở trạng thái đã biết.

Về lý thuyết, bạn có thể thiết lập hibernate.hbm2ddl.auto=updateđể cập nhật cơ sở dữ liệu của mình với các thay đổi cho mô hình của mình, nhưng tôi không tin vào cơ sở dữ liệu sản xuất. Một phiên bản trước đó của tài liệu nói rằng ít nhất đây là thử nghiệm; Tôi không biết tình trạng hiện tại.

Do đó, đối với cơ sở dữ liệu sản xuất của chúng tôi, không được đặt hibernate.hbm2ddl.auto- mặc định là không thực hiện thay đổi cơ sở dữ liệu. Thay vào đó, chúng tôi tự tạo một tập lệnh cập nhật SQL DDL áp dụng các thay đổi từ phiên bản này sang phiên bản tiếp theo.


5
Trên thực tế, theo tài liệu, tạo-thả tạo các bảng cơ sở dữ liệu và loại bỏ chúng khi nhà máy phiên được đóng rõ ràng. Nó không bỏ các bảng khi nhà máy phiên được tạo.
Frans

4
Không, cả tạo-thả và tạo thả các bảng khi tạo phiên làm việc, sau đó tạo-thả cũng làm rơi các bảng khi đóng phiên. Xem stackoverflow.com/a/6752698/1536382
Testo Testini

việc tạo hibernate.hbm2ddl.auto = tạo-thả trong sản xuất có thể dẫn đến một số thời gian chờ kết nối trong sản xuất không?
METTAIBI

51

Tôi sẽ sử dụng liquidibase để cập nhật db của bạn. Tính năng cập nhật lược đồ của hibernate thực sự chỉ phù hợp với nhà phát triển trong khi họ đang phát triển các tính năng mới. Trong tình huống sản xuất, việc nâng cấp db cần được xử lý cẩn thận hơn.


6
Xem stackoverflow.com/questions/221379/ vì lý do tại sao bạn không nên sử dụng hbm2ddl để sản xuất.
Nathan Voxland

51

Mặc dù nó là một bài viết khá cũ nhưng như tôi đã làm một số nghiên cứu về chủ đề này nên đã nghĩ đến việc chia sẻ nó.

ngủ đông.hbm2ddl.auto

Theo tài liệu này, nó có thể có bốn giá trị hợp lệ:

tạo | cập nhật | xác nhận | tạo ra

Sau đây là giải thích về hành vi được hiển thị bởi các giá trị sau:

  • tạo : - tạo lược đồ, dữ liệu hiện tại trước đó (nếu có) trong lược đồ bị mất
  • cập nhật: - cập nhật lược đồ với các giá trị đã cho.
  • xác nhận: - xác nhận lược đồ. Nó không làm thay đổi DB.
  • tạo-thả: - tạo lược đồ với việc hủy dữ liệu hiện tại trước đó (nếu có). Nó cũng loại bỏ lược đồ cơ sở dữ liệu khi SessionFactory bị đóng.

Sau đây là những điểm quan trọng đáng chú ý:

  • Trong trường hợp cập nhật , nếu lược đồ không có trong DB thì lược đồ được tạo.
  • Trong trường hợp xác nhận , nếu lược đồ không tồn tại trong DB, nó không được tạo. Thay vào đó, nó sẽ đưa ra một lỗi: -Table not found:<table name>
  • Trong trường hợp tạo-thả , lược đồ không bị hủy khi đóng phiên. Nó chỉ giảm khi đóng sessionFactory.
  • Trong trường hợp nếu tôi đưa ra bất kỳ giá trị nào cho thuộc tính này (giả sử abc, thay vì bốn giá trị được thảo luận ở trên) hoặc nó chỉ để trống. Nó cho thấy hành vi sau đây:

    -Nếu lược đồ không có trong DB: - Nó tạo lược đồ

    -Nếu lược đồ có mặt trong DB: - cập nhật lược đồ.


Đây thực sự là một điểm rất quan trọng mà lược đồ sẽ được tạo nếu nó không tồn tại, khi "cập nhật" được sử dụng.
yuranos

tạo-thả bị mâu thuẫn khi so sánh các câu lệnh "Giải thích hành vi" và "Điểm quan trọng".
VNT

2
Sự khác biệt giữa cập nhậttrống là gì?
yashjain12yj

46

Đầu tiên, các giá trị có thể cho thuộc tính hbm2ddlcấu hình là các giá trị sau:

  • none- Không có hành động được thực hiện. Các lược đồ sẽ không được tạo ra.
  • create-only - Lược đồ cơ sở dữ liệu sẽ được tạo.
  • drop - Lược đồ cơ sở dữ liệu sẽ được loại bỏ và tạo sau đó.
  • create - Lược đồ cơ sở dữ liệu sẽ được loại bỏ và tạo sau đó.
  • create-drop- Lược đồ cơ sở dữ liệu sẽ được loại bỏ và tạo sau đó. Khi đóng SessionFactory, lược đồ cơ sở dữ liệu sẽ bị loại bỏ.
  • validate - Lược đồ cơ sở dữ liệu sẽ được xác nhận bằng cách sử dụng ánh xạ thực thể.
  • update - Lược đồ cơ sở dữ liệu sẽ được cập nhật bằng cách so sánh lược đồ cơ sở dữ liệu hiện có với ánh xạ thực thể.

Tôi dành riêng một bài đăng trên blog cho các chiến lược tạo DDL Hibernate phổ biến nhất :

  1. Tiện hibernate.hbm2ddl.auto="update"lợi nhưng kém linh hoạt nếu bạn có kế hoạch thêm chức năng hoặc thực thi một số tập lệnh tùy chỉnh.
  2. Cách tiếp cận linh hoạt nhất là sử dụng Flyway .

Tuy nhiên, ngay cả khi bạn sử dụng Flyway, bạn vẫn có thể tạo tập lệnh di chuyển ban đầu bằng hbm2ddl. Trong bài viết này , bạn có thể thấy cách bạn có thể kết hợp Mô hình thực thể JPA với Mô hình bảng jOOQ.


27

hibernate.hbm2ddl.auto tự động xác nhận và xuất DDL sang lược đồ khi sessionFactory được tạo.

Theo mặc định, nó không tự động thực hiện bất kỳ sáng tạo hoặc sửa đổi nào trên DB. Nếu người dùng đặt một trong các giá trị dưới đây thì nó đang thực hiện thay đổi lược đồ DDL.

  • tạo - thực hiện tạo một lược đồ

    <entry key="hibernate.hbm2ddl.auto" value="create">
  • cập nhật - cập nhật lược đồ hiện có

    <entry key="hibernate.hbm2ddl.auto" value="update">
  • xác thực - xác thực lược đồ hiện có

    <entry key="hibernate.hbm2ddl.auto" value="validate">
  • tạo-thả - tạo và thả lược đồ tự động khi một phiên bắt đầu và kết thúc

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

2
Còn <entry key = "hibernate.hbm2ddl.auto" value = "none"> thì sao?
VNT

17

Nếu bạn không muốn sử dụng Chuỗi trong ứng dụng của mình và đang tìm kiếm các hằng số được xác định trước, hãy xem org.hibernate.cfg.AvailableSettingslớp được bao gồm trong JAR Hibernate, nơi bạn sẽ tìm thấy hằng số cho tất cả các cài đặt có thể. Trong trường hợp của bạn chẳng hạn:

/**
 * 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
Tại sao tham chiếu đến hơn 700 dòng tệp dài trên câu trả lời thẳng với gần 500 vole up?
Pavel Niedoba

... Câu hỏi đó không có nghĩa gì cả. Tại sao có những thứ? Tại sao tôi còn ở đây?
đặc biệt

8
  • validate: xác nhận lược đồ, không có thay đổi nào xảy ra với cơ sở dữ liệu.
  • update: cập nhật lược đồ với truy vấn thực hiện hiện tại.
  • create: tạo lược đồ mới mỗi lần và phá hủy dữ liệu trước đó.
  • create-drop: bỏ lược đồ khi ứng dụng bị dừng hoặc SessionFactory được đóng rõ ràng.

Tài liệu tham khảo 'chính thức' là gì? - chỉ tự hỏi ...
Dirk Schumacher

7

Tôi nghĩ bạn nên tập trung vào

SchemaExport Class 

Lớp này làm cho cấu hình của bạn động Vì vậy, nó cho phép bạn chọn bất kỳ bộ nào bạn thích nhất ...

Thanh toán [SchemaExport]


4

validate: Nó xác nhận lược đồ và không thay đổi DB.
Giả sử bạn đã thêm một cột mới trong tệp ánh xạ và thực hiện thao tác chèn, nó sẽ đưa ra một Ngoại lệ "thiếu cột XYZ" vì lược đồ hiện có khác với đối tượng bạn sẽ chèn. Nếu bạn thay đổi bảng bằng cách thêm cột mới theo cách thủ công thì thực hiện thao tác Chèn thì chắc chắn nó sẽ chèn tất cả các cột cùng với cột mới vào Bảng. Có nghĩa là nó không thực hiện bất kỳ thay đổi / thay đổi lược đồ / bảng hiện có.

update: nó thay đổi bảng hiện có trong cơ sở dữ liệu khi bạn thực hiện thao tác. Bạn có thể thêm hoặc xóa các cột với tùy chọn này của hbm2ddl. Nhưng nếu bạn định thêm một cột mới là 'KHÔNG NULL' thì nó sẽ bỏ qua việc thêm cột cụ thể đó vào DB. Bởi vì Bảng phải trống nếu bạn muốn thêm cột 'KHÔNG NULL' vào bảng hiện có.


3

Kể từ 5.0 , giờ đây bạn có thể tìm thấy các giá trị đó một cách chuyên dụng Enum: org.hibernate.boot.SchemaAutoTooling(được nâng cao với giá trị NONEkể từ 5.2).

Hoặc thậm chí tốt hơn, kể từ 5.1 , bạn cũng có thể sử dụng kết hợp các hành động DDL Hibernate "kế thừa".org.hibernate.tool.schema.Action Enum

Nhưng , bạn chưa thể cấu hình một DataSourcechương trình với điều này. Nó sẽ tốt hơn để sử dụng kết hợp với org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTOnhưng mã hiện tại mong đợi một Stringgiá trị (trích từ SessionFactoryBuilderImpl):

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

enumGiá trị và nội bộ của cả hai org.hibernate.boot.SchemaAutoToolingorg.hibernate.tool.schema.Actionkhông được công khai.

Dưới đây, một DataSourcecấu hình lập trình mẫu (được sử dụng trong các ứng dụng Spring Boot của tôi) sử dụng một gambit nhờ .name().toLowerCase()nhưng nó chỉ hoạt động với các giá trị không có dấu gạch ngang (không phải create-dropví dụ):

@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

Người tìm kiếm giá trị mặc định ...

Nó được viết bằng mã nguồn ở phiên bản 2.0.5 của spring-boot và 1.1.0 tại JpaProperIES:

    /**
     * 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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.