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

使用@IdGeneratorType搭配OnExecutionGenerator的DDL生成异常问询

自定义OnExecutionGenerator生成器配合@IdGeneratorType的DDL问题解决

可以将实现OnExecutionGenerator的生成器与@IdGeneratorType配合使用,但你的配置缺少了DDL生成所需的元数据声明,这才导致Id字段没有被标记为generated by default as identity。

问题根源

IdentityGenerator只实现了OnExecutionGenerator接口,负责运行时的ID生成逻辑,但Hibernate生成DDL时,需要明确知道该字段的生成策略类型(比如IDENTITY)。@IdGeneratorType只是告诉Hibernate使用哪个生成器类,并不会自动为字段添加DDL层面的identity属性。

两种可行的修复方案

方案一:让自定义生成器实现PersistentAttributeMetadataContributor

通过实现这个接口,主动向Hibernate提供字段的生成策略元数据,这样DDL生成时就会把Id字段标记为identity类型:

public class MyIdGeneratorImpl extends IdentityGenerator implements PersistentAttributeMetadataContributor {
    @Override
    public void contribute(PersistentAttribute<?, ?> attribute, MetadataBuildingContext context) {
        if (attribute instanceof SingularAttribute<?, ?> singularAttribute && singularAttribute.isId()) {
            ((SingularAttributeImpl<?, ?>) singularAttribute).setGenerationStrategy(GenerationType.IDENTITY);
        }
    }
}

方案二:在自定义注解上添加@GeneratedValue

直接在@MyIdGenerator注解上追加@GeneratedValue(strategy = GenerationType.IDENTITY),明确指定DDL生成策略:

@Retention(RUNTIME)
@Target({METHOD, FIELD})
@IdGeneratorType(MyIdGeneratorImpl.class)
@GeneratedValue(strategy = GenerationType.IDENTITY) // 新增该行
public @interface MyIdGenerator{}

关于插入SQL的疑问

你看到的插入语句里的default是Hibernate根据生成器的OnExecutionGenerator逻辑生成的,但因为实际表字段不是identity类型,数据库无法识别这个default,最终还是会传入NULL值,触发NULL not allowed for column Id的约束错误。修复DDL生成后,数据库会自动生成Id值,这个问题就会消失。


内容的提问来源于stack exchange,提问作者Vojtěch Sýkora

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:58:17