Путаница: @NotNull против @Column(nullable = false)
Когда они появляются на поле / добытчик
@Entity
какая разница между ними? (Я сохраняю сущность через Hibernate).К какой структуре и / или спецификации принадлежит каждый из них?
@NotNull
находится внутриjavax.validation.constraints
, вjavax.validation.constraints.NotNull
Javadoc это говоритАннотированный элемент не должен быть нулевым
но это не говорит о представлении элемента в базе данных, так почему бы мне добавить ограничение
nullable=false
в колонку?
3 ответа
@NotNull
является аннотацией JSR 303 Bean Validation Это не имеет ничего общего с ограничениями базы данных. Однако, поскольку Hibernate является эталонной реализацией JSR 303, он разумно распознает эти ограничения и преобразует их в ограничения базы данных, поэтому вы получаете два по цене одного. @Column(nullable = false)
способ JPA для объявления столбца не равным NULL. Т.е. первый предназначен для проверки, а второй - для указания деталей схемы базы данных. Вы просто получаете дополнительную (и добро пожаловать!) Помощь от Hibernate в аннотациях проверки.
В последних версиях провайдера JPA гибернации применяются ограничения проверки bean-компонентов (JSR 303), например @NotNull
в DDL по умолчанию (спасибо hibernate.validator.apply_to_ddl property
по умолчанию true
). Но нет никакой гарантии, что другие провайдеры JPA сделают или даже смогут это сделать.
Вы должны использовать аннотации проверки бобов, такие как @NotNull
чтобы убедиться, что для свойств bean-компонентов задано непустое значение при проверке Java-бинов в JVM (это не имеет ничего общего с ограничениями базы данных, но в большинстве случаев должно соответствовать им).
Вы должны дополнительно использовать аннотацию JPA как @Column(nullable = false)
дать подсказки провайдеру jpa для создания правильного DDL для создания столбцов таблицы с необходимыми ограничениями базы данных. Если вы можете или хотите положиться на поставщика JPA, такого как Hibernate, который по умолчанию применяет ограничения проверки bean-компонентов к DDL, то вы можете их опустить.
JPA @Column
Аннотации
В nullable
атрибут @Column
аннотация имеет две цели:
- он используется инструментом генерации схемы
- он используется Hibernate во время очистки контекста постоянства
Инструмент создания схемы
Инструмент создания схемы HBM2DDL переводит @Column(nullable = false)
атрибут сущности к NOT NULL
ограничение для связанного столбца таблицы при генерации CREATE TABLE
заявление.
Как я объяснил в Руководстве пользователя Hibernate, лучше использовать такой инструмент, как Flyway, вместо того, чтобы полагаться на механизм HBM2DDL для создания схемы базы данных.
Сброс контекста постоянства
При сбросе контекста постоянства Hibernate ORM также использует @Column(nullable = false)
атрибут объекта:
new Nullability( session ).checkNullability( values, persister, true );
Если проверка не удалась, Hibernate выдаст сообщение 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]
);
}
Для получения дополнительных сведений о том, как работает механизм очистки Hibernate, ознакомьтесь с этой статьей.
Проверка бина @NotNull
Аннотации
В @NotNull
аннотация определяется Bean Validation, и, как Hibernate ORM является самой популярной реализацией JPA, самой популярной реализацией Bean Validation является структура https://hibernate.org/validator/.
При использовании Hibernate Validator вместе с Hibernate ORM, Hibernate Validator выдаст сообщение ConstraintViolation
при проверке сущности.
Интересно отметить, что все источники подчеркивают, что @Column(nullable=false) используется только для генерации DDL.
Однако даже если аннотации @NotNull нет, а для параметра hibernate.check_nullability задано значение true, Hibernate выполнит проверку сущностей, которые необходимо сохранить.
Он вызовет PropertyValueException, сообщив, что "свойство not-null ссылается на нулевое или временное значение", если атрибуты nullable = false не имеют значений, даже если такие ограничения не реализованы на уровне базы данных.
Дополнительная информация о параметре hibernate.check_nullability доступна здесь: http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html.