@Column(nullable=false) 验证应用程序级别的空值检查

3

根据我的理解,nullable = false(例如对于列customerid)仅适用于使用Hibernate创建模式,并且在持久化之前不应进行任何类型的验证。我的数据库列没有此类约束(它可以接受null值),但在将具有customerid为null的实体持久化时,会出现此错误。

Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value :b
    at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:111) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:55) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
    at 

我将我的spring boot版本更新到2.4.2之后,这个错误开始不断出现。

实体类

public class FaceIndexResponse extends AuditEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column(name="customer_id",nullable = false)
    private String customerId;
    @Column(name="application_id")
    private String appid;}

我尝试保存上述实体的服务类

public IndexFacesResult handle(FaceIndexModel model) throws IOException{
    FaceIndexResponse response=new FaceIndexResponse();
    response.setAppid(model.getApplicationId);
    faceIndexResponseJpa.save(response);
 }


                                   Table "public.face_index_response"
     Column     |            Type             | Collation | Nullable |             Default              
----------------+-----------------------------+-----------+----------+----------------------------------
 id             | integer                     |           | not null | generated by default as identity
 customer_id    | character varying(64)       |           |          | 
 application_id | character varying(64)       |           |          | 

你能分享一下抛出这个异常的代码吗? - Naqi
你检查了数据库表吗?请再次确认数据库中的列是否可为空。确保刷新您已经打开的任何数据库客户端窗口。 - Naqi
数据库表中的yes列不包含任何约束。 - NubMaster
奇怪。我一直以为这就是它应该工作的方式:数据库抽象层强制执行它,所以您不必拥有列约束。 - Bohemian
如果属性应该接受null,并且没有数据库约束,那么你为什么一开始使用nullable = false呢? - crizzis
显示剩余3条评论
2个回答

2

这是由于Spring Boot 2.3.x的更改所致:

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#validation-starter-no-longer-included-in-web-starters

从 #19550 开始,Web 和 WebFlux starters 默认不再依赖验证 starter。如果您的应用程序正在使用验证功能,例如发现 javax.validation.* 导入未被解析,则需要自己添加 starter。
从2.3.0开始,验证 starter 不再包含在 Web starters 中。这意味着 Bean Validation 不再在类路径上,导致 Hibernate 的行为发生变化。Hibernate 文档中指出了这一点。

https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#_bean_validation_options

hibernate.check_nullability(例如true或false) 启用空值检查。如果标记为非null的属性为null,则会引发异常。
如果类路径中存在Bean Validation并使用Hibernate注释,则默认为false,否则为true。
因此,可以通过两种方式解决突然发生的验证:
1.按照PDiddly的答案所示将spring.jpa.properties.hibernate.check_nullability设置为false 2.或者向项目添加spring-boot-starter-validation依赖
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

(或者如果您更喜欢,可以返回bean验证的各个依赖项)


1

嘿,谢谢,但我已经尝试过了。我的配置文件中没有这样的属性。 之前它一直很好用,但是随着Spring Boot升级和Hibernate版本的变化,出现了这个问题。 - NubMaster
2
你是否启用了Hibernate Validators?来自SessionFactoryOptionsBuilder(Hibernate核心):this.checkNullability = cfgService.getSetting(CHECK_NULLABILITY, BOOLEAN, true);以及来自TypeSafeActivator:// 当Bean Validation存在时,在核心级别上取消非空跟踪,除非用户明确要求 if (cfgService.getSettings().get(Environment.CHECK_NULLABILITY) == null) {activationContext.getSessionFactory().getSessionFactoryOptions().setCheckNullability(false); } - PDiddly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接