当它们出现在@Entity 的字段/getter 上时,它们之间有什么区别? (我通过休眠保持实体)。它们各自属于什么框架和/或规范? @NotNull 位于 javax.validation.constraints 中。在 javax.validation.constraints.NotNull javadoc 中,它说注释元素不能为空,但它没有说明元素在数据库中的表示,那么为什么我要在列中添加约束 nullable=false 呢?
@NotNull
是一个 JSR 303 Bean Validation 注释。它与数据库约束本身无关。然而,由于 Hibernate 是 JSR 303 的参考实现,它智能地获取这些约束并将它们转换为您的数据库约束,因此您以一个的价格获得两个。 @Column(nullable = false)
是 JPA 将列声明为非空的方式。即前者用于验证,后者用于指示数据库模式详细信息。您只是从 Hibernate 获得了一些关于验证注释的额外(欢迎!)帮助。
最新版本的休眠 JPA 提供程序默认将 bean 验证约束 (JSR 303) 像 @NotNull
应用于 DDL(感谢 hibernate.validator.apply_to_ddl property
默认为 true
)。但是不能保证其他 JPA 提供者会这样做,甚至有能力这样做。
您应该使用像 @NotNull
这样的 bean 验证注释来确保在 JVM 中验证 java bean 时将 bean 属性设置为非空值(这与数据库约束无关,但在大多数情况下应该与它们相对应)。
您还应该使用像 @Column(nullable = false)
这样的 JPA 注释来为 jpa 提供程序提供提示,以生成正确的 DDL,以创建具有所需数据库约束的表列。如果您可以或想要依赖像 Hibernate 这样的 JPA 提供程序,它默认将 bean 验证约束应用于 DDL,那么您可以省略它们。
JPA @Column 注释
@Column
注释的 nullable
属性有两个用途:
它由模式生成工具使用
它由 Hibernate 在刷新持久性上下文期间使用
模式生成工具
HBM2DDL 架构生成工具在生成 CREATE TABLE
语句时将 @Column(nullable = false)
实体属性转换为关联表列的 NOT NULL
约束。
正如我在 Hibernate 用户指南中解释的那样,最好使用像 Flyway 这样的工具,而不是依赖 HBM2DDL 机制来生成数据库模式。
持久性上下文刷新
在刷新 Persistence Context 时,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]
);
}
Bean 验证 @NotNull 注解
@NotNull
注释由 Bean Validation 定义,就像 Hibernate ORM 是最流行的 JPA 实现一样,最流行的 Bean Validation 实现是 Hibernate Validator 框架。
将 Hibernate Validator 与 Hibernate ORM 一起使用时,Hibernate Validator 将在验证实体时抛出 ConstraintViolation
。
@NotNull
就足够了,我应该两者兼有吗? @Basic(optional=false)
是否与 @Column(nullable = false)
相同?
@NotNull
。我认为我没有使用过 @Basic(optional=false)
。我不确定 Hibernate 是否使用那个。我仅在生成架构时使用 @Column(nullable = false)
。总而言之,使用 FlywayDB 定义您的数据库架构,并在每一层上进行验证:Web、控制器、服务层。
有趣的是,所有来源都强调 @Column(nullable=false) 仅用于 DDL 生成。
然而,即使没有 @NotNull 注解,并且 hibernate.check_nullability 选项设置为 true,Hibernate 也会对要持久化的实体进行验证。
如果 nullable=false 属性没有值,它将抛出 PropertyValueException 说“非空属性引用空值或瞬态值”,即使在数据库层中没有实现此类限制。
此处提供有关 hibernate.check_nullability 选项的更多信息:http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping。
不定期副业成功案例分享
@NotNull
、@Size
、@Min
、@Max
等,并将它们转换为数据库约束。