Плутанина: @NotNull vs. @Column (nullable = false) із JPA та Hibernate


242
  1. Коли вони з’являються на полі / геттера @Entity, яка різниця між ними? (Я наполягаю на об'єкті через сплячку ).

  2. До якої основи та / або специфікації належить кожна з них?

  3. @NotNullзнаходиться в межах javax.validation.constraints. У javax.validation.constraints.NotNulljavadoc сказано

    Помічений елемент не повинен бути нульовим

    але це не говорить про представлення елемента в базі даних, то чому б я додав обмеження nullable=falseдо стовпця?

Відповіді:


328

@NotNullє анотацією на перевірку квасолі JSR 303 . Це не має нічого спільного з самими обмеженнями в базі даних. Оскільки Hibernate є еталонною реалізацією JSR 303, однак вона розумно підбирає ці обмеження і переводить їх у обмеження для бази даних, тому ви отримуєте два за ціну одного. @Column(nullable = false)- це спосіб JPA оголошення стовпця недійсним. Тобто перший призначений для перевірки, а останній для вказівки деталей схеми бази даних. Ви просто отримуєте додаткову (і ласкаво просимо!) Допомогу від Hibernate щодо анотацій щодо перевірки.


2
Дякую! Отже, якщо я хочу, щоб мої стійкості JPA не були прив’язані до реалізації режиму глибокого сну (тобто зміни до EJB3), тоді я повинен використовувати обидва анотації (щоб заборонити null як у полі, так і в його стовпці)?
rapt

3
Не знаю. Немає специфікацій, які б стверджували, що постачальник JPA повинен розпізнавати примітки JSR 303, але це не означає, що інші постачальники цього не роблять. Я не можу сказати, чи є, чи ні.
Райан Стюарт

7
Провайдерам JPA не потрібно надавати реалізацію JSR303, але вони відповідають вимогам, що забезпечують можливість інтеграції з будь-якою реалізацією JSR303 третьої сторони. Отже, хоча Hibernate надає JSR303, ви можете з будь-якої причини вирішити не використовувати їх та йти з кимось іншим або використовувати реалізацію JPA, як openJPA, а використовувати іншу для надання JSR303. Також зверніть увагу, що реалізація JPA Hibernate також є EJB3. Неправильно сказати "якщо я хочу, щоб мої наполегливості JPA не були прив'язані до режиму сплячки (тобто зміни до EJB3)" JPA є частиною специфікації EJB3.
Шахзеб

5
@Shahzeb: Питання не в тому, хто підтримує / надає перевірку JSR 303. Йдеться про яких ОРЗ (s) визнати JSR 303 анотацій , як @NotNull, @Size, @Min, @Maxі т.д., і переводити ті в обмеженнях бази даних.
Райан Стюарт

1
Так, але мій коментар є дійсним у контексті того, що ОП запитав у наступному коментарі, якого ви не знали.
Шахзеб

18

В останніх версіях сплячого постачальника JPA застосовуються обмеження перевірки квасолі (JSR 303), як @NotNullDDL, за замовчуванням (завдяки hibernate.validator.apply_to_ddl propertyналаштуванням за замовчуванням true). Але немає жодної гарантії, що інші постачальники JPA роблять або навіть мають можливість це робити.

Ви повинні використовувати анотації перевірки bean, як, @NotNullщоб переконатися, що властивості bean встановлені ненульовим значенням під час перевірки Java-бобів у JVM (це не має нічого спільного з обмеженнями в базі даних, але в більшості ситуацій має відповідати їм).

Вам слід додатково використовувати анотацію JPA, як, @Column(nullable = false)щоб дати підказкам постачальника jpa для створення потрібного DDL для створення стовпців таблиць із необхідними обмеженнями в базі даних. Якщо ви можете або хочете покластися на такого постачальника послуг JPA, як Hibernate, який застосовує обмеження перевірки квасолі до DDL за замовчуванням, ви можете їх опустити.


10

Цікаво зазначити, що всі джерела підкреслюють, що @Column (nullable = false) використовується лише для створення DDL.

Однак, навіть якщо немає анотації @NotNull, а для параметра hibernate.check_nullability встановлено значення true, Hibernate виконає перевірку об'єктів, які потрібно зберігати.

Він кине PropertyValueException, кажучи, що "не-null посилання властивості є нульовим або перехідним значенням", якщо nullable = false атрибути не мають значень, навіть якщо такі обмеження не реалізовані в рівні бази даних.

Більше інформації про параметр hibernate.check_nullability можна отримати тут: http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping .


7

@ColumnАнотація JPA

nullableАтрибут @Columnанотації має дві мети:

  • він використовується інструментом генерації схеми
  • він використовується Hibernate під час промивання контексту стійкості

Інструмент генерації схем

Інструмент генерації схеми HBM2DDL перетворює @Column(nullable = false)атрибут сутності в NOT NULLобмеження для пов'язаного стовпця таблиці під час генерації CREATE TABLEоператора.

Як я пояснив у Посібнику зі сплячого режиму , краще використовувати такий інструмент, як Flyway, а не покладатися на механізм HBM2DDL для створення схеми бази даних.

Контекст витримки

Під час промивання контексту постійності Hibernate ORM також використовує @Column(nullable = false)атрибут сутності:

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

Якщо перевірка не вдасться, Hibernate викине a PropertyValueExceptionта запобігає виконанню оператора INSERT або 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]
        );    
}

Більш детально про те, як працює механізм промивання в режимі зимування, перегляньте цю статтю .

@NotNullАнотація перевірки квасолі

@NotNullАнотацій визначається Bean Validation і, так само , як Hibernate ORM є найбільш популярною реалізацією JPA, найбільш популярною реалізація Bean Validation є Hibernate Validator рамки.

Якщо ви використовуєте Hibernate Validator разом із Hibernate ORM, Hibernate Validator викидає а, ConstraintViolationколи перевіряє сутність.


Чому ви стверджуєте, що проліт краще, ніж створювати схему?
Андронік

1
Це гарне спостереження. Я оновив відповідь за посиланням.
Влад Михальча

Дякуємо за довідку та чудову відповідь!
Андронік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.