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)相同吗