使用@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
相关产品推荐
相关产品推荐

