You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用diffChangeLog时Java @NotNull约束未生成到Liquibase变更日志

问题

我有一个包含id字段的Java Entity,现在为该实体新增了一个字段,并为其添加了Java Bean校验约束@NotNull,但通过diffChangeLog命令生成的Liquibase变更日志中未包含该约束信息。请问为何约束信息未被生成到变更日志中?


Gradle脚本

val projectVersion: String by project
val liquibaseVersion: String = "4.20.0"
val liquibaseGradlePluginVersion: String = "2.0.4"

plugins {
    java
    id("org.springframework.boot") apply false
    id("org.liquibase.gradle") apply true
}

dependencies {

    implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))

    liquibaseRuntime(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))

    implementation("org.postgresql:postgresql")
    implementation("info.picocli:picocli:4.6.3")

    implementation("org.liquibase:liquibase-core:$liquibaseVersion")
    implementation("org.liquibase:liquibase-gradle-plugin:$liquibaseGradlePluginVersion")

    implementation("org.hibernate:hibernate-core")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.liquibase.ext:liquibase-hibernate5:$liquibaseVersion")

    implementation("com.fasterxml.jackson.core:jackson-core")
    implementation("com.fasterxml.jackson.core:jackson-databind")
    implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml")

    liquibaseRuntime("info.picocli:picocli:4.6.3")
    liquibaseRuntime("org.liquibase:liquibase-core:$liquibaseVersion")
    liquibaseRuntime("org.postgresql:postgresql")
    liquibaseRuntime("org.liquibase.ext:liquibase-hibernate5:$liquibaseVersion")
    liquibaseRuntime("org.springframework.boot:spring-boot-starter-data-jpa")
    liquibaseRuntime(sourceSets.getByName("main").output)
}

tasks.register("propertiesForDiffChangeLog") {
    doLast {
        propertiesForDiffChangeLog()
    }
}

tasks.getByName("diffChangeLog").dependsOn(tasks.getByName("propertiesForDiffChangeLog"))
tasks.getByName("diffChangeLog").dependsOn(JavaPlugin.CLASSES_TASK_NAME)

fun propertiesForDiffChangeLog() {

    liquibase {

        val schemaName = "test"

        activities.register("main") {
            this.arguments = mapOf(
                    "driver" to "org.postgresql.Driver",
                    "changeLogFile" to "src/main/resources/config/liquibase/changelog/TODO_describe-change.xml",
                    "referenceUrl" to "hibernate:spring:com.test?dialect=org.hibernate.dialect.PostgreSQLDialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy",
                    "url" to "jdbc:postgresql://localhost:5432/postgres",
                    "username" to "postgres",
                    "password" to password,
                    "defaultSchemaName" to "$schemaName"
            )
        }
    }
}

Java Entity

import javax.persistence.*;
import javax.validation.constraints.NotNull;

@Entity
@Table(name = "item")
public class ItemEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Long id;

  @NotNull // <-- 未出现在Liquibase变更日志中
  @Column(name = "another")
  private String anotherField;

  /** Hibernate跨VM兼容所需的无参构造函数。 */
  public ItemEntity() {}
}

生成的Liquibase变更日志

<changeSet author="me" id="1687774415103-1">
    <addColumn tableName="item">
        <column name="another" type="varchar(255)"/>
    </addColumn>
</changeSet>

解答

核心原因是你混淆了Java Bean校验约束和数据库层面非空约束的定位:

  • @NotNull属于Java Bean Validation(JSR-380)规范,仅作用于应用运行时的对象数据校验,不会自动映射为数据库表的非空约束。Liquibase的diffChangeLog是对比Hibernate映射的数据库模型与实际库的差异,而Hibernate默认不会将Bean校验注解转换为数据库约束。

要让Liquibase生成数据库级别的非空约束,需做以下调整:

  1. 添加JPA的@Column(nullable = false)注解
    这是JPA规范中用于定义数据库字段非空的注解,Hibernate会将其映射为数据库表的非空约束,Liquibase对比时就能识别到该差异。修改后的字段代码如下:

    @NotNull // 保留应用层Bean校验
    @Column(name = "another", nullable = false) // 定义数据库层面的非空约束
    private String anotherField;
    
  2. 确认Liquibase Hibernate扩展配置有效性
    你的Gradle已引入liquibase-hibernate5扩展,它负责读取Hibernate的映射元数据。确保referenceUrl配置正确,能扫描到目标Entity类,这样Liquibase才能获取到nullable = false的配置信息。

  3. 重新生成变更日志
    调整完Entity注解后,重新执行diffChangeLog命令,生成的变更日志会包含非空约束定义,示例如下:

    <changeSet author="me" id="xxx">
        <addColumn tableName="item">
            <column name="another" type="varchar(255)" nullable="false"/>
        </addColumn>
    </changeSet>
    

总结来说,@NotNull管的是应用层的数据合法性校验,和数据库约束无关;要生成数据库非空约束,必须使用JPA的@Column(nullable = false)注解。

内容的提问来源于stack exchange,提问作者bobbyrne01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:43:17