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

rap*_*apt 225 persistence hibernate hibernate-annotations ejb-3.0 jpa-2.0

  1. 当它们出现在a的场/吸气器上时@Entity,它们之间有什么区别?(我通过Hibernate坚持实体).

  2. 每个人都属于哪个框架和/或规范?

  3. @NotNull位于javax.validation.constraints.在javax.validation.constraints.NotNulljavadoc中它说

    带注释的元素不能为null

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

Rya*_*art 309

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

  • JPA提供程序不需要提供JSR303实现,但按照规范要求提供与任何第三方JSR303实现集成的能力.因此,虽然Hibernate确实提供了JSR303,但您可以出于任何原因决定不使用它们并与其他人一起使用或使用像openJPA这样的JPA实现并使用其他人来提供JSR303.另外注意Hibernate的JPA实现也是EJB3.It说的不对'如果我希望我的JPA持久性不依赖于Hibernate实现(即更改为EJB3)'JPA是EJB3规范的一部分. (7认同)
  • @Shahzeb:问题不在于谁支持/提供JSR 303验证.这是关于哪些ORM识别JSR 303注释,如`@NotNull`,`@ Size`,`@ Min`,`@ Max`等,并将它们转换为数据库约束. (5认同)
  • 我不知道.没有规范说JPA提供者必须识别JSR 303注释,但这并不意味着其他提供者不会.我不能说是否有. (3认同)
  • 谢谢!因此,如果我希望我的JPA持久性不依赖于Hibernate实现(即更改为EJB3),那么我必须使用两个注释(在字段及其列中禁止null)? (2认同)

小智 15

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

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

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


Vla*_*cea 13

JPA@Column注释

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

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

模式生成工具

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

正如我在解释中Hibernate的用户指南,它更好地使用工具,如迁飞,而不是依靠就是hbm2ddl机制生成的数据库架构。

持久化上下文刷新

在刷新 Persistence Context 时,Hibernate ORM 还使用@Column(nullable = false)实体属性:

new Nullability( session ).checkNullability( values, persister, true );
Run Code Online (Sandbox Code Playgroud)

如果验证失败,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]
        );    
}
Run Code Online (Sandbox Code Playgroud)

Bean 验证@NotNull注解

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

当 Hibernate Validator 与 Hibernate ORM 一起使用时,Hibernate ValidatorConstraintViolation在验证实体时会抛出 a 。


小智 9

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