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

Java 混淆:@NotNull与@Column(nullable=false)与JPA和Hibernate,java,hibernate,jpa,persistence,hibernate-annotations,Java,Hibernate,Jpa,Persistence,Hibernate Annotations,当它们出现在@实体的字段/getter上时,它们之间有什么区别?(我通过休眠保存实体) 它们各自属于什么框架和/或规范 @NotNull位于javax.validation.constraints中。在javax.validation.constraints.NotNulljavadoc中,它说 带注释的元素不能为null 但是它没有提到元素在数据库中的表示,那么为什么我要将约束nullable=false添加到列中呢 是一个注释。它与数据库约束本身无关。然而,由于Hibernate是JSR30

当它们出现在
@实体的字段/getter上时,它们之间有什么区别?(我通过休眠保存实体)

  • 它们各自属于什么框架和/或规范

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

    带注释的元素不能为null

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


  • 是一个注释。它与数据库约束本身无关。然而,由于Hibernate是JSR303的参考实现,它智能地提取这些约束并将它们转换为数据库约束,因此您可以用一个约束的价格获得两个约束。是将列声明为非空的JPA方法。即,前者用于验证,后者用于指示数据库架构细节。您刚刚从Hibernate获得了一些关于验证注释的额外(欢迎!)帮助。

    Hibernate JPA provider的最新版本将bean验证约束(JSR 303)应用于DDL,如默认情况下的
    @NotNull
    (感谢
    Hibernate.validator.apply_to_DDL属性
    默认为
    true
    )。但也不能保证其他JPA提供商能做到,甚至有能力做到这一点

    在JVM中验证java bean时,应该使用bean验证注释,如
    @NotNull
    ,以确保bean属性设置为none-null值(这与数据库约束无关,但在大多数情况下应该对应于它们)


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

    值得注意的是,所有来源都强调@Column(nullable=false)仅用于DDL生成

    但是,即使没有@NotNull注释,并且hibernate.check_nullability选项设置为true,hibernate也将对要持久化的实体执行验证

    如果nullable=false属性没有值,它将抛出PropertyValueException,说明“notnull属性引用null或瞬态值”,即使在数据库层中没有实现此类限制

    有关hibernate.check_nullability选项的详细信息,请访问:

    JPA
    @列
    注释
    @Column
    注释的
    nullable
    属性有两个用途:

    • 它由模式生成工具使用
    • Hibernate在刷新持久性上下文时使用它
    模式生成工具 生成
    CREATE table
    语句时,HBM2DDL架构生成工具将
    @列(nullable=false)
    实体属性转换为关联表列的
    非NULL
    约束

    正如我在中所解释的,最好使用类似的工具,而不是依赖HBM2DDL机制来生成数据库模式

    持久性上下文刷新 刷新持久性上下文时,Hibernate ORM还使用
    @列(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验证定义,就像Hibernate ORM是最流行的JPA实现一样,最流行的Bean验证实现是框架


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

    谢谢!因此,如果我希望我的JPA持久性不与Hibernate实现绑定(即更改为EJB3),那么我必须使用这两种注释(以禁止字段及其列中的null)?我不知道。没有规定JPA提供者必须识别JSR303注释,但这并不意味着其他提供者不能识别。我不能说是否有。JPA提供程序不需要提供JSR303实现,但需要按照规范提供与任何第三方JSR303实现集成的能力。因此,尽管Hibernate确实提供JSR303,但无论出于何种原因,您都可以决定不使用他们的JSR303,或者使用像openJPA这样的JPA实现,并使用其他人来提供JSR303。还要注意,Hibernate的JPA实现也是EJB3。说“如果我不想让我的JPA持久性与Hibernate绑定,这是不正确的实现(即更改为EJB3)“JPA是EJB3规范的一部分。@Shahzeb:问题不在于谁支持/提供JSR303验证。这是关于哪些ORM识别JSR303注释,如
    @NotNull
    @Size
    @Min
    @Max
    ,等等。,并将其转换为数据库约束。是的,但我的评论在OP在随后的评论中提出的内容(您不知道)的上下文中是有效的。您为什么说flyway比生成模式更好?这是一个很好的观察结果。我用参考链接更新了答案。谢谢你的参考和伟大的答案!谢谢你的回答。如果我不想使用模式生成工具或者
    @NotNull
    就足够了,我应该同时使用这两种工具吗?并且
    @Basic(可选=false)
    @列(可空=f)相同吗