JPA嵌入式类@NotNull约束未生效,如何在嵌入表保留约束?
解决JPA中@Embeddable类属性@NotNull注解不生成DDL约束的问题
你遇到的核心问题是:JPA生成DDL时,@Embeddable类内部属性的@NotNull注解没有被转换为数据库表的NOT NULL约束。本质原因是你使用的@NotNull属于Bean Validation(JSR-380)的运行时校验注解,而非JPA规范中用于定义数据库列属性的注解,默认情况下JPA实现(如Hibernate)不会自动将校验注解映射为DDL约束。
解决方案1:使用JPA标准注解@Column(nullable = false)
这是最通用、兼容性最好的方案,完全符合JPA规范。直接在@Embeddable类的属性上添加JPA的@Column注解,显式指定列不可为空:
@Embeddable public class Meta { @NotNull // 保留用于业务逻辑层的运行时校验(可选) @Column(nullable = false) private Instant created; @NotNull // 保留用于业务逻辑层的运行时校验(可选) @Column(nullable = false) private Instant lastModified; @NotNull // 保留用于业务逻辑层的运行时校验(可选) @Length(min = 1, max = 63) // 保留用于业务逻辑层的运行时校验(可选) @Column(nullable = false, length = 63) private String digest; }
修改后生成的DDL会自动为对应字段添加NOT NULL约束:
CREATE TABLE public.contact ( id bigint NOT NULL, full_name character varying(63) NOT NULL, display_name character varying(63), email_address character varying(63), created timestamp(6) with time zone NOT NULL, last_modified timestamp(6) with time zone NOT NULL, digest character varying(63) NOT NULL );
解决方案2:启用Hibernate的校验注解转DDL功能(仅适用于Hibernate)
如果你使用Hibernate作为JPA实现,可以通过配置参数让Hibernate自动将Bean Validation注解转换为DDL约束。根据你的项目环境添加配置:
- 传统JPA项目(persistence.xml):
<property name="hibernate.validator.apply_to_ddl" value="true"/>
- Spring Boot项目(application.properties):
spring.jpa.properties.hibernate.validator.apply_to_ddl=true
这种方式无需修改代码,但属于Hibernate的扩展特性,换用其他JPA实现时会失效,因此优先推荐方案1。
注意事项
你在Contact类中对@Embedded的meta字段添加的@NotNull,仅用于校验整个Meta对象不为null,不会影响其内部属性的数据库列约束,因此内部属性仍需单独配置。
内容的提问来源于stack exchange,提问作者Peter Molnar
相关产品推荐
相关产品推荐

