Thuộc tính spring.jpa.hibernate.ddl-auto hoạt động chính xác như thế nào trong Spring?


127

Tôi đang làm việc trên dự án ứng dụng khởi động Spring của mình và nhận thấy rằng, đôi khi có lỗi hết thời gian kết nối với Cơ sở dữ liệu của tôi trên một máy chủ khác (SQL Server). Điều này đặc biệt xảy ra khi tôi cố gắng thực hiện một số di chuyển tập lệnh FlyWaynhưng nó hoạt động sau vài lần thử.

Sau đó, tôi nhận thấy rằng tôi đã không chỉ định spring.jpa.hibernate.ddl-autotrong tệp thuộc tính của mình. Tôi đã thực hiện một số nghiên cứu và nhận thấy rằng nó được khuyến khích bổ sung spring.jpa.hibernate.ddl-auto= create-droptrong quá trình phát triển. Và thay đổi nó thành: spring.jpa.hibernate.ddl-auto= nonein production.

Nhưng tôi thực sự không hiểu nó thực sự hoạt động như thế nào và làm thế nào để ngủ đông tạo ra lược đồ cơ sở dữ liệu bằng cách sử dụng create-drophoặc nonegiá trị. Bạn có thể vui lòng giải thích về mặt kỹ thuật nó thực sự hoạt động như thế nào và các khuyến nghị sử dụng thuộc tính này trong quá trình phát triển và trên máy chủ sản xuất là gì. Cảm ơn bạn


1
FWIW JPA 2.1 có thuộc tính tiêu chuẩn javax.persistence.schema-generation.database.action, vì vậy bạn không thực sự thấy cần phải sử dụng các thuộc tính cụ thể của nhà cung cấp JPA để tạo giản đồ.
Neil Stockton

@NeilStockton Một ý tưởng mà chúng tôi đang khám phá với Hibernate 6 là khả năng có thể kiểm soát việc tạo lược đồ khác nhau dựa trên các danh mục; ví dụ: bảng orm của bạn có thể là nonenhưng bạn có thể muốn các bảng Hibernate Search và Envers của mình được tạo bằng cách sử dụng updatevì chúng được quản lý nội bộ bởi các dự án đó và bạn không muốn tự mình quản lý chúng theo cách thủ công. Ngay bây giờ, chúng tôi kiểm soát điều này trên toàn cầu cho tất cả các bảng bất kể nguồn gốc / nguồn của chúng. Đây sẽ là lý do để sử dụng các tùy chọn dành riêng cho nhà cung cấp nếu bạn muốn sử dụng tùy chọn này.
Naros

Câu trả lời:


213

Đối với bản ghi, thuộc spring.jpa.hibernate.ddl-autotính là Spring Data JPA cụ thể và là cách của họ để chỉ định một giá trị cuối cùng sẽ được chuyển đến Hibernate theo thuộc tính mà nó biết hibernate.hbm2ddl.auto,.

Các giá trị create, create-drop, validate, và updatevề cơ bản ảnh hưởng đến cách thức quản lý công cụ schema sẽ thao tác database schema lúc khởi động.

Ví dụ: updatethao tác sẽ truy vấn API trình điều khiển JDBC để lấy siêu dữ liệu cơ sở dữ liệu và sau đó Hibernate so sánh mô hình đối tượng mà nó tạo ra dựa trên việc đọc các lớp được chú thích của bạn hoặc ánh xạ HBM XML và sẽ cố gắng điều chỉnh giản đồ một cách nhanh chóng.

Các updatehoạt động ví dụ sẽ cố gắng thêm các cột mới, ràng buộc, vv nhưng sẽ không bao giờ loại bỏ một cột hoặc hạn chế có thể đã tồn tại trước đó nhưng không còn thực hiện như một phần của mô hình đối tượng từ một chạy trước.

Thông thường trong các tình huống trường hợp thử nghiệm, bạn có thể sẽ sử dụng create-dropđể tạo lược đồ của mình, trường hợp thử nghiệm của bạn thêm một số dữ liệu giả, bạn chạy thử nghiệm và sau đó trong quá trình dọn dẹp trường hợp thử nghiệm, các đối tượng lược đồ bị loại bỏ, để lại một cơ sở dữ liệu trống.

Trong quá trình phát triển, người ta thường thấy các nhà phát triển sử dụng updateđể tự động sửa đổi lược đồ để thêm các bổ sung mới khi khởi động lại. Nhưng hãy hiểu lại, điều này không loại bỏ một cột hoặc ràng buộc có thể tồn tại từ các lần thực thi trước đó mà không còn cần thiết.

Trong sản xuất, bạn thường rất nên sử dụng nonehoặc đơn giản là không chỉ định thuộc tính này. Đó là vì thông lệ đối với các DBA là xem xét các tập lệnh di chuyển để thay đổi cơ sở dữ liệu, đặc biệt nếu cơ sở dữ liệu của bạn được chia sẻ trên nhiều dịch vụ và ứng dụng.


11
Vâng, không bao giờ sử dụng tạo ddl trong sản xuất. Chúng tôi tạo các tập lệnh ban đầu cho cấu trúc bảng bằng ddl và sử dụng DBA trong quá trình này. Sau đó, chúng tôi bao gồm các tập lệnh db như một phần của đơn vị triển khai và thực thi chúng bằng Flyway khi ứng dụng được triển khai. Khi chúng tôi cần sửa đổi cơ sở dữ liệu, chúng tôi thêm các tập lệnh mới vào phiên bản tiếp theo của ứng dụng và triển khai theo giai đoạn. Flyway sẽ tự động phát hiện phiên bản hiện tại và chạy các tập lệnh cần thiết để đưa cơ sở dữ liệu lên phiên bản mới nhất. Nếu mọi thứ hoạt động, chúng tôi triển khai sản xuất.
Klaus Groenbaek

1
điều gì xảy ra nếu chúng tôi không chỉ định thuộc tính này? ví dụ: tôi có <bean id = "sessionFactory" class = "org.springframework.orm.hibernate5.LocalSessionFactoryBean"> ... <prop key = "hibernate.hbm2ddl.auto"> cập nhật của riêng tôi </prop> Tôi đã có cái này và vì một số lý do mà bảng của tôi luôn bị loại bỏ, cho đến khi tôi thêm thuộc tính được đề cập ở trên ;; ps: xin lỗi vì mẫu mã)
Ţîgan Ion

11
Tại sao không có validatetrong Production Env?
Shamal Karunarathne,

20
@ShamalKarunarathne Các ứng dụng có thể sử dụng validatetrong sản xuất, nhưng thông thường đó phải là cài đặt bạn sử dụng trong môi trường chất lượng / thử nghiệm của mình để xác minh rằng các tập lệnh cơ sở dữ liệu bạn đã viết hoặc áp dụng cho công cụ di chuyển cơ sở dữ liệu của mình là chính xác. Một lý do khác không nên sử dụng validatetrong sản xuất là nó có thể gây tắc nghẽn trong quá trình khởi động ứng dụng của bạn, đặc biệt nếu mô hình đối tượng của bạn có kích thước khá rộng hoặc nếu các yếu tố liên quan đến mạng khác phát huy tác dụng.
Naros

1
Nếu không có một dấu vết ngăn xếp chính xác thì rất khó để suy đoán; tuy nhiên, suy đoán đầu tiên của tôi sẽ orderlà trình phân tích cú pháp SQL diễn giải sai vì đó là một từ khóa nếu nó không được thoát.
Naros
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.