困惑:@NotNull vs @Column(nullable = false)

时间:2011-09-16 02:20:12

标签: hibernate persistence ejb-3.0 jpa-2.0 hibernate-annotations

  1. 当它们出现在@Entity的字段/ getter上时,它们之间有什么区别? (我通过 Hibernate 坚持实体。)

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

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

      

    带注释的元素不能为空

    但是它没有提到数据库中元素的表示,那么我为什么要将约束nullable=false添加到列中?

4 个答案:

答案 0 :(得分:287)

@NotNullJSR 303 Bean Validation注释。它与数据库约束本身无关。但是,由于Hibernate是JSR 303的参考实现,它会智能地了解这些约束并将它们转换为数据库约束,因此您可以以一个的价格获得两个约束。 @Column(nullable = false)是JPA声明列不为null的方式。即前者用于验证,后者用于指示数据库架构详细信息。您只是从验证注释中获得Hibernate的一些额外(并且欢迎!)帮助。

答案 1 :(得分:12)

最新版本的hibernate JPA提供程序默认情况下将@NotNull之类的bean验证约束(JSR 303)应用于DDL(感谢hibernate.validator.apply_to_ddl property默认为true)。但是不能保证其他JPA提供商能够做到甚至有能力做到这一点。

在验证JVM中的java bean时,您应该使用bean验证注释(如@NotNull来确保将bean属性设置为非空值(这与数据库约束无关,但在大多数情况下)情况应与他们相对应。)

您还应该使用像@Column(nullable = false)这样的JPA注释来为jpa提供程序提示生成正确的DDL,以便使用您想要的数据库约束创建表列。如果您可以或者想要依赖像Hibernate这样的JPA提供程序,默认情况下会将bean验证约束应用于DDL,那么您可以省略它们。

答案 2 :(得分:9)

JPA @Column批注

nullable批注的@Column属性具有两个目的:

  • 由模式生成工具使用
  • Hibernate在刷新持久性上下文时使用它

模式生成工具

当生成@Column(nullable = false)语句时,HBM2DDL模式生成工具将NOT NULL实体属性转换为关联表列的CREATE TABLE约束。

正如我在Hibernate User Guide中所述,最好使用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刷新机制如何工作的更多详细信息,请查看this article

Bean验证@NotNull注释

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

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

答案 3 :(得分:8)

有趣的是,所有消息来源都强调@Column(nullable = false)仅用于DDL生成。

但是,即使没有@NotNull注释,并且hibernate.check_nullability选项设置为true,Hibernate也会执行要保留的实体的验证。

如果nullable = false属性没有值,它将抛出PropertyValueException,说“not-null属性引用null或transient值”,即使数据库层中没有实现这样的限制。

有关hibernate.check_nullability选项的更多信息,请访问:http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping