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

如何为String类型主键创建自定义序列生成器?Hibernate报错求助

解决Hibernate String类型主键使用Sequence生成器报错的问题

错误原因:Hibernate默认的sequence生成器会生成整数类型的ID值,但你的主键字段ext_source_id定义为String类型,类型不匹配导致抛出IdentifierGenerationException。

以下是几种可行的解决方法:

  • 方法一:使用SequenceStyleGenerator并配置类型转换
    修改hbm.xml中的主键生成器配置,指定使用org.hibernate.id.enhanced.SequenceStyleGenerator,通过参数将序列生成的数值转换为String类型:

    <class name="CmRetroEvt" table="CM_RETRO_EVT" schema="CISADM" >
        <id name="ext_source_id" type="string" column="EXT_SOURCE_ID">
            <generator class="org.hibernate.id.enhanced.SequenceStyleGenerator">
                <param name="sequence_name">EXT_SOURCE_ID_SEQ_NBR</param>
                <param name="optimizer">none</param>
                <param name="increment_size">1</param>
                <param name="value_converter">org.hibernate.type.StringType</param>
            </generator>
        </id>
        <!-- 其他属性配置 -->
    </class>
    
  • 方法二:自定义标识符生成器
    编写一个继承自SequenceGenerator的自定义生成器,将序列生成的数值转为String:

    import org.hibernate.id.SequenceGenerator;
    import org.hibernate.engine.spi.SessionImplementor;
    import java.io.Serializable;
    
    public class StringSequenceGenerator extends SequenceGenerator {
        @Override
        public Serializable generate(SessionImplementor session, Object obj) {
            // 将序列生成的Long值转为String
            return String.valueOf(super.generate(session, obj));
        }
    }
    

    然后在hbm.xml中引用该自定义生成器(注意替换实际包路径):

    <class name="CmRetroEvt" table="CM_RETRO_EVT" schema="CISADM" >
        <id name="ext_source_id" type="string" column="EXT_SOURCE_ID">
            <generator class="com.your.package.StringSequenceGenerator">
                <param name="sequence_name">EXT_SOURCE_ID_SEQ_NBR</param>
            </generator>
        </id>
        <!-- 其他属性配置 -->
    </class>
    
  • 方法三:手动分配ID(适用于不需要完全自动生成的场景)
    通过原生SQL查询序列的下一个值,转换为String后手动设置到实体对象(以Oracle语法为例,其他数据库需调整查询语句):

    Session session = sessionFactory.getCurrentSession();
    Long nextSeqVal = (Long) session.createNativeQuery("SELECT EXT_SOURCE_ID_SEQ_NBR.NEXTVAL FROM DUAL").uniqueResult();
    
    CmRetroEvt entity = new CmRetroEvt();
    entity.setExt_source_id(String.valueOf(nextSeqVal));
    session.save(entity);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:05:47