Nhầm lẫn: @NotNull so với @Column (nullable = false) với JPA và Hibernate


242
  1. Khi chúng xuất hiện trên một trường / getter của an @Entity, sự khác biệt giữa chúng là gì? (Tôi kiên trì thực thể thông qua Hibernate ).

  2. Khung và / hoặc đặc điểm kỹ thuật mà mỗi một trong số chúng thuộc về?

  3. @NotNullnằm trong phạm vi javax.validation.constraints. Trong javax.validation.constraints.NotNulljavadoc, nó nói

    Phần tử chú thích không được rỗng

    nhưng nó không nói về biểu diễn của phần tử trong cơ sở dữ liệu, vậy tại sao tôi lại thêm ràng buộc nullable=falsevào cột?

Câu trả lời:


328

@NotNulllà một chú thích xác thực Bean JSR 303 . Nó không có gì để làm với các ràng buộc cơ sở dữ liệu chính nó. Vì Hibernate là triển khai tham chiếu của JSR 303, tuy nhiên, nó thông minh chọn ra các ràng buộc này và chuyển chúng thành các ràng buộc cơ sở dữ liệu cho bạn, vì vậy bạn nhận được hai với giá của một. @Column(nullable = false)là cách JPA tuyên bố một cột là không null. Tức là cái trước được dùng để xác nhận và cái sau để chỉ ra chi tiết lược đồ cơ sở dữ liệu. Bạn chỉ cần nhận thêm một số trợ giúp (và hoan nghênh!) Từ Hibernate trên các chú thích xác thực.


2
Cảm ơn! Vì vậy, nếu tôi muốn sự kiên trì JPA của tôi không bị ràng buộc với việc triển khai Hibernate (tức là thay đổi thành EJB3) thì tôi phải sử dụng cả hai chú thích (để cấm null trong cả trường và cột của nó)?
mừng

3
Tôi không biết. Không có thông số kỹ thuật nào nói rằng nhà cung cấp JPA phải nhận ra các chú thích JSR 303, nhưng điều đó không có nghĩa là các nhà cung cấp khác không có. Tôi không thể nói dù có hay không.
Ryan Stewart

7
Các nhà cung cấp JPA không bắt buộc phải cung cấp triển khai JSR303 nhưng theo thông số kỹ thuật được yêu cầu để cung cấp khả năng tích hợp với bất kỳ triển khai JSR303 của bên thứ ba nào. Vì vậy, trong khi Hibernate cung cấp JSR303, vì bất kỳ lý do gì, bạn quyết định không sử dụng chúng và đi với người khác hoặc sử dụng triển khai JPA như openJPA và sử dụng người khác để cung cấp JSR303. Cũng lưu ý rằng triển khai JPA của Hibernate cũng là EJB3. 'nếu tôi muốn sự kiên trì JPA của tôi không bị ràng buộc với việc triển khai Hibernate (tức là thay đổi thành EJB3)' JPA là một phần của đặc tả EJB3.
Shahzeb

5
@Shahzeb: Câu hỏi không phải là về người hỗ trợ / cung cấp xác thực JSR 303. Đó là về mà ORM (s) nhận JSR 303 chú thích như @NotNull, @Size, @Min, @Max, vv, và chuyển những thành trở ngại cơ sở dữ liệu.
Ryan Stewart

1
Có nhưng nhận xét của tôi là hợp lệ trong bối cảnh OP đã hỏi trong bình luận tiếp theo mà bạn không biết.
Shahzeb

18

Các phiên bản gần đây nhất của nhà cung cấp JPA ngủ đông áp dụng các ràng buộc xác thực bean (JSR 303) như @NotNullDDL theo mặc định (nhờ hibernate.validator.apply_to_ddl propertymặc định là true). Nhưng không có gì đảm bảo rằng các nhà cung cấp JPA khác làm hoặc thậm chí có khả năng làm điều đó.

Bạn nên sử dụng các chú thích xác thực bean như @NotNullđể đảm bảo rằng các thuộc tính bean được đặt thành giá trị null, khi xác thực các java bean trong JVM (điều này không liên quan gì đến các ràng buộc cơ sở dữ liệu, nhưng trong hầu hết các tình huống nên tương ứng với chúng).

Bạn cũng nên sử dụng chú thích JPA như @Column(nullable = false)để đưa ra gợi ý cho nhà cung cấp jpa để tạo DDL phù hợp để tạo các cột trong bảng với các ràng buộc cơ sở dữ liệu mà bạn muốn. Nếu bạn có thể hoặc muốn dựa vào nhà cung cấp JPA như Hibernate, nơi áp dụng các ràng buộc xác thực bean cho DDL theo mặc định, thì bạn có thể bỏ qua chúng.


10

Điều thú vị cần lưu ý, tất cả các nguồn đều nhấn mạnh rằng @Column (nullable = false) chỉ được sử dụng để tạo DDL.

Tuy nhiên, ngay cả khi không có chú thích @NotNull và tùy chọn hibernate.check_nullability được đặt thành true, Hibernate sẽ thực hiện xác thực các thực thể để được duy trì.

Nó sẽ ném PropertyValueException nói rằng "thuộc tính không null tham chiếu giá trị null hoặc giá trị nhất thời", nếu nullable = false các thuộc tính không có giá trị, ngay cả khi các hạn chế đó không được thực hiện trong lớp cơ sở dữ liệu.

Thông tin thêm về tùy chọn hibernate.check_nullability có sẵn tại đây: http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping .


7

@ColumnChú thích JPA

Các nullablethuộc tính của @Columnchú thích có hai mục đích:

  • nó được sử dụng bởi công cụ tạo lược đồ
  • nó được Hibernate sử dụng trong quá trình xóa Bối cảnh dai dẳng

Công cụ tạo lược đồ

Công cụ tạo lược đồ HBM2DDL chuyển @Column(nullable = false)thuộc tính thực thể thành một NOT NULLràng buộc cho cột bảng được liên kết khi tạo CREATE TABLEcâu lệnh.

Như tôi đã giải thích trong Hướng dẫn sử dụng Hibernate , tốt hơn là sử dụng một công cụ như Flyway thay vì dựa vào cơ chế HBM2DDL để tạo lược đồ cơ sở dữ liệu.

Bối cảnh dai dẳng

Khi xóa Bối cảnh liên tục, Hibernate ORM cũng sử dụng @Column(nullable = false)thuộc tính thực thể:

new Nullability( session ).checkNullability( values, persister, true );

Nếu xác thực thất bại, Hibernate sẽ ném một PropertyValueExceptionvà ngăn chặn câu lệnh INSERT hoặc UPDATE được thực thi một cách cần thiết:

if ( !nullability[i] && value == null ) {
    //check basic level one nullablilty
    throw new PropertyValueException(
            "not-null property references a null or transient value",
            persister.getEntityName(),
            persister.getPropertyNames()[i]
        );    
}

Để biết thêm chi tiết về cách cơ chế xả Hibernate hoạt động, hãy xem bài viết này .

@NotNullChú thích xác thực Bean

Các @NotNullchú thích được xác định bởi Bean Validation và, giống như Hibernate ORM là phổ biến thực hiện JPA nhất, Bean Validation thực hiện phổ biến nhất là Hibernate Validator khuôn khổ.

Khi sử dụng Trình xác thực Hibernate cùng với ORM Hibernate, Trình ConstraintViolationxác thực Hibernate sẽ ném một khi xác thực thực thể.


Tại sao bạn nói rằng flyway tốt hơn là tạo lược đồ?
Andronicus

1
Đó là một quan sát tốt. Tôi cập nhật câu trả lời với một liên kết tham khảo.
Vlad Mihalcea

Cảm ơn đã tham khảo và câu trả lời tuyệt vời!
Andronicus
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.