混淆:JPA 和 Hibernate 中的 @NotNull 与 @Column(nullable = false)

问题描述 投票:0回答:5
  1. 当它们出现在

    @Entity
    的字段/吸气剂上时,它们之间有什么区别? (我通过 Hibernate 持久化实体)。

  2. 它们各自属于什么框架和/或规范?

  3. @NotNull
    位于
    javax.validation.constraints
    内。在
    javax.validation.constraints.NotNull
    javadoc 中它说

    被注释的元素不能为null

    但它没有谈到元素在数据库中的表示,那么为什么我要向列添加约束

    nullable=false

java hibernate jpa persistence hibernate-annotations
5个回答
349
投票

@NotNull
是一个 JSR 303 Bean Validation 注释。它与数据库约束本身无关。然而,由于 Hibernate 是 JSR 303 的参考实现,因此它会智能地获取这些约束并将其转换为数据库约束,因此您只需花费一个约束即可获得两个约束。
@Column(nullable = false)
是 JPA 声明列不为空的方式。 IE。前者用于验证,后者用于指示数据库模式详细信息。您只是从 Hibernate 获得了关于验证注释的一些额外(欢迎!)帮助。


20
投票

最新版本的 hibernate JPA 提供程序默认将

@NotNull
等 Bean 验证约束 (JSR 303) 应用到 DDL(感谢
hibernate.validator.apply_to_ddl property
默认为
true
)。但不能保证其他 JPA 提供商能够做到甚至有能力做到这一点。

在 JVM 中验证 java beans 时,您应该使用像

@NotNull
这样的 bean 验证注释来确保 bean 属性设置为非空值(这与数据库约束无关,但在大多数情况下应该对应于他们)。

您还应该使用 JPA 注释(如

@Column(nullable = false)
)为 jpa 提供程序提供提示,以生成正确的 DDL,用于创建具有所需数据库约束的表列。如果您可以或想要依赖像 Hibernate 这样的 JPA 提供程序,它默认将 bean 验证约束应用于 DDL,那么您可以忽略它们。


19
投票

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

Bean 验证
@NotNull
注释

@NotNull
注释由 Bean Validation 定义,就像 Hibernate ORM 是最流行的 JPA 实现一样,最流行的 Bean Validation 实现是 Hibernate Validator 框架。

当将 Hibernate Validator 与 Hibernate ORM 一起使用时,Hibernate Validator 将在验证实体时抛出

ConstraintViolation


13
投票

有趣的是,所有来源都强调 @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


0
投票
@NotNull @Column(可为空= false)
通常仅用于检查java对象的字段的不可空性 通常仅用于 DDL 生成(⇒ 您可以在 java 对象的字段中创建空字段,但不能将其持久化到数据库列)
Bean 验证规范的一部分,例如
hibernate-validator
JPA 规范的一部分
Hibernate 足够聪明,能够理解如果使用
@NotNull
来阻止 java 对象字段上的空字段,则意味着 db 中的相应列也不应该有空值。因此,使用 hibernate 时,这提供了字段和数据库级别的非空性
使用 hibernate 时,除了数据库列级别不可空性验证之外,它还仅在以下情况下提供 java 对象字段级别验证:
spring.jpa.properties.hibernate.check_nullability=true

TL;DR 建议: 使用

@NotNull
,因为数据库脚本通常不是由 hibernate 创建的。

© www.soinside.com 2019 - 2024. All rights reserved.