Reputation: 12240
When they appear on a field/getter of an @Entity
, what is the difference between them? (I persist the Entity through Hibernate).
What framework and/or specification each one of them belongs to?
@NotNull
is located within javax.validation.constraints
. In the javax.validation.constraints.NotNull
javadoc it says
The annotated element must not be null
but it does not speak of the element's representation in the database, so why would I add the constraint nullable=false
to the column?
Upvotes: 267
Views: 191085
Reputation: 154190
@Column
AnnotationThe nullable
attribute of the @Column
annotation has two purposes:
The HBM2DDL schema generation tool translates the @Column(nullable = false)
entity attribute to a NOT NULL
constraint for the associated table column when generating the CREATE TABLE
statement.
As explained in the Hibernate User Guide, it's better to use a tool like Flyway instead of relying on the HBM2DDL mechanism for generating the database schema. In which case, HBM2DDL migration scripts can be captured into Flyway versioned migrations.
When flushing the Persistence Context, Hibernate ORM also uses the @Column(nullable = false)
entity attribute:
new Nullability( session ).checkNullability( values, persister, true );
If the validation fails, Hibernate will throw a PropertyValueException
, and prevents the INSERT or UPDATE statement to be executed needlessly:
if ( !nullability[i] && value == null ) {
//check basic level one nullability
throw new PropertyValueException(
"not-null property references a null or transient value",
persister.getEntityName(),
persister.getPropertyNames()[i]
);
}
@NotNull
AnnotationThe @NotNull
annotation is defined by Bean Validation and, just like Hibernate ORM is the most popular JPA implementation, the most popular Bean Validation implementation is the Hibernate Validator framework.
When using Hibernate Validator along with Hibernate ORM, Hibernate Validator will throw a ConstraintViolation
when validating the entity.
Upvotes: 24
Reputation: 2214
@NotNull | @Column(nullable=false) |
---|---|
Generally used just for checking java object's field's non nullability | Generally used just for DDL generation (⇒ you can create a null field in java object's field but cannot persist it to db column) |
Part of Bean Validation Specification like hibernate-validator |
Part of JPA specification |
Hibernate is clever enough to understand that if @NotNull is used to block null fields on java object's field, it means the corresponding columns in db should also not have null values. So when using hibernate, this provides both field and db level non nullability |
When using hibernate, along with db column level non nullability validation, it also provides java object field level validation only if spring.jpa.properties.hibernate.check_nullability=true |
TL;DR Recommendation: Use
@NotNull
as DB scripts are generally not created by hibernate.
Upvotes: 1
Reputation: 329
Interesting to note, all sources emphasize that @Column(nullable=false) is used only for DDL generation.
However, even if there is no @NotNull annotation, and hibernate.check_nullability option is set to true, Hibernate will perform validation of entities to be persisted.
It will throw PropertyValueException saying that "not-null property references a null or transient value", if nullable=false attributes do not have values, even if such restrictions are not implemented in the database layer.
More information about hibernate.check_nullability option is available here: http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping.
Upvotes: 13
Reputation: 201
The most recent versions of hibernate JPA provider applies the bean validation constraints (JSR 303) like @NotNull
to DDL by default (thanks to hibernate.validator.apply_to_ddl property
defaults to true
). But there is no guarantee that other JPA providers do or even have the ability to do that.
You should use bean validation annotations like @NotNull
to ensure, that bean properties are set to a none-null value, when validating java beans in the JVM (this has nothing to do with database constraints, but in most situations should correspond to them).
You should additionally use the JPA annotation like @Column(nullable = false)
to give the jpa provider hints to generate the right DDL for creating table columns with the database constraints you want. If you can or want to rely on a JPA provider like Hibernate, which applies the bean validation constraints to DDL by default, then you can omit them.
Upvotes: 20
Reputation: 128939
@NotNull
is a JSR 303 Bean Validation annotation. It has nothing to do with database constraints itself. As Hibernate is the reference implementation of JSR 303, however, it intelligently picks up on these constraints and translates them into database constraints for you, so you get two for the price of one. @Column(nullable = false)
is the JPA way of declaring a column to be not-null. I.e. the former is intended for validation and the latter for indicating database schema details. You're just getting some extra (and welcome!) help from Hibernate on the validation annotations.
Upvotes: 356