Zamieszanie: @NotNull vs. @Column (nullable = false) z JPA i Hibernacja

242
  1. Kiedy pojawiają się na polu / polu pobierania @Entity, jaka jest między nimi różnica? (Utrzymuję Entity poprzez Hibernację ).

  2. Do jakiej struktury i / lub specyfikacji należy każdy z nich?

  3. @NotNullznajduje się w obrębie javax.validation.constraints. W javax.validation.constraints.NotNulljavadoc jest napisane

    Element z adnotacjami nie może mieć wartości NULL

    ale nie mówi o reprezentacji elementu w bazie danych, więc dlaczego miałbym dodawać ograniczenie nullable=falsedo kolumny?

skupiony
źródło

Odpowiedzi:

328

@NotNullto adnotacja JSR 303 Bean Validation . Nie ma to nic wspólnego z samymi ograniczeniami bazy danych. Ponieważ Hibernacja jest referencyjną implementacją JSR 303, inteligentnie wychwytuje te ograniczenia i tłumaczy je na ograniczenia bazy danych, więc otrzymujesz dwa za cenę jednego. @Column(nullable = false)jest sposobem JPA na zadeklarowanie, że kolumna ma wartość inną niż null. Tj. Pierwszy służy do sprawdzania poprawności, a drugi do wskazywania szczegółów schematu bazy danych. Dostajesz tylko dodatkową (i mile widzianą!) Pomoc od Hibernacji na adnotacjach walidacyjnych.

Ryan Stewart
źródło
2
Dzięki! Więc jeśli chcę, aby moja trwałość JPA nie była powiązana z implementacją Hibernacji (tj. Zmiana na EJB3), to muszę użyć obu adnotacji (aby zabronić wartości null zarówno w polu, jak i jego kolumnie)?
rapt
3
Nie wiem Nie ma specyfikacji, która mówi, że dostawca JPA musi rozpoznawać adnotacje JSR 303, ale to nie znaczy, że inni dostawcy nie. Nie mogę powiedzieć, czy coś robi, czy nie.
Ryan Stewart
7
Dostawcy JPA nie są zobowiązani do zapewnienia implementacji JSR303, ale zgodnie ze specyfikacją wymaganą do zapewnienia możliwości integracji z dowolną implementacją JSR303 innej firmy. Więc chociaż Hibernate zapewnia JSR303, możesz z jakiegokolwiek powodu zdecydować, aby nie używać ich i iść z kimś innym lub użyć implementacji JPA, takiej jak openJPA, i użyć kogoś innego, aby dostarczyć JSR303. Zwróć też uwagę, że implementacja Hibernate JPA to także EJB3. „jeśli chcę, aby moja trwałość JPA nie była powiązana z implementacją Hibernacji (tj. zmiana na EJB3)” JPA jest częścią specyfikacji EJB3.
Shahzeb,
5
@Shahzeb: Pytanie nie dotyczy tego, kto obsługuje / zapewnia weryfikację JSR 303. Chodzi o których ORM (y) rozpoznać JSR 303 adnotacje, takie jak @NotNull, @Size, @Min, @Max, itd., A te przekładają się ograniczeń baz danych.
Ryan Stewart
1
Tak, ale mój komentarz jest ważny w kontekście tego, o co OP poprosił w kolejnym komentarzu, którego nie znałeś.
Shahzeb,
18

Najnowsze wersje dostawcy hibernacji JPA @NotNulldomyślnie stosują ograniczenia sprawdzania fasoli (JSR 303), takie jak DDL (dzięki hibernate.validator.apply_to_ddl propertydomyślnemu ustawieniutrue ). Ale nie ma gwarancji, że inni dostawcy JPA to robią, a nawet mają taką możliwość.

Powinieneś używać adnotacji sprawdzania poprawności komponentów bean, @NotNullaby upewnić się, że właściwości komponentu bean są ustawione na wartość zerową, podczas sprawdzania poprawności ziaren Java w JVM (nie ma to nic wspólnego z ograniczeniami bazy danych, ale w większości przypadków powinny być z nimi zgodne).

Dodatkowo należy użyć adnotacji JPA, takiej jak @Column(nullable = false)wskazówki dla dostawcy jpa, aby wygenerować odpowiedni DDL do tworzenia kolumn tabeli z żądanymi ograniczeniami bazy danych. Jeśli możesz lub chcesz polegać na dostawcy JPA, takim jak Hibernate, który domyślnie stosuje ograniczenia sprawdzania fasoli do DDL, możesz je pominąć.

Sebastian Theek
źródło
10

Co ciekawe, wszystkie źródła podkreślają, że @Column (nullable = false) jest używany tylko do generowania DDL.

Jednak nawet jeśli nie ma adnotacji @NotNull, a opcja hibernacji.check_nullability jest ustawiona na wartość true, Hibernacja przeprowadzi weryfikację jednostek, które mają zostać utrwalone.

Zgłasza wyjątek PropertyValueException, mówiąc, że „właściwość niezerowa odwołuje się do wartości zerowej lub przejściowej”, jeśli atrybuty zerowalne = fałszywe nie mają wartości, nawet jeśli takie ograniczenia nie są zaimplementowane w warstwie bazy danych.

Więcej informacji o opcji hibernacji.check_nullability można znaleźć tutaj: http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping .

Aleksandar Radulović
źródło
7

@ColumnAdnotacja JPA

nullableAtrybut @Columnadnotacji ma dwa cele:

  • jest używany przez narzędzie do generowania schematów
  • jest używany przez Hibernację podczas opróżniania kontekstu trwałości

Narzędzie do generowania schematów

Narzędzie do generowania schematu HBM2DDL tłumaczy @Column(nullable = false)atrybut encji na NOT NULLograniczenie dla powiązanej kolumny tabeli podczas generowania CREATE TABLEinstrukcji.

Jak wyjaśniłem w Hibernate User Guide , lepiej jest używać narzędzia takiego jak Flyway zamiast polegać na mechanizmie HBM2DDL do generowania schematu bazy danych.

Kontekst utrzymywania koloru

Podczas opróżniania kontekstu trwałości Hibernacja ORM używa również @Column(nullable = false)atrybutu encji:

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

Jeśli sprawdzanie poprawności się nie powiedzie, Hibernacja rzuci a PropertyValueExceptioni uniemożliwi wykonanie instrukcji INSERT lub UPDATE:

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]
        );    
}

Więcej informacji na temat działania mechanizmu spłukiwania hibernacji można znaleźć w tym artykule .

@NotNullAdnotacja walidacji komponentu Bean

@NotNullAdnotacja jest zdefiniowany przez Bean Validation i, podobnie jak Hibernate ORM jest najpopularniejszym wdrażanie WZP, najpopularniejszy realizacja Bean Validation jest Hibernate Validator ramy.

Podczas korzystania z Hibernacji Walidatora wraz z Hibernacją ORM, Hibernacja Walidatora wyrzuci a ConstraintViolationpodczas sprawdzania poprawności jednostki.

Vlad Mihalcea
źródło
Dlaczego twierdzisz, że flyway jest lepszy niż generowanie schematu?
Andronicus
1
To dobra obserwacja. Zaktualizowałem odpowiedź linkiem referencyjnym.
Vlad Mihalcea
Dzięki za referencje i świetną odpowiedź!
Andronicus