grails不想用系统生成的字段id可以自己改

ORM映射配置解析
本文介绍了一种静态映射配置方法,详细解释了如何通过指定属性来实现对象关系映射(ORM),包括ID生成策略、字段名及版本控制等。

static mapping = {
        id generator: 'assigned', name: "personId", column: "person_id"
        version false
    }

<think>我们正在解决Grails项目从Oracle迁移到达梦数据库后,使用save操作时ID无法自动生成的问题。可能原因:达梦数据库的序列机制与Oracle同,或者Grails的映射配置需要调整。步骤分析:1.GrailsID生成策略:在Oracle中通常使用序列(sequence),达梦数据库也支持序列,但语法和用法可能有差异。2.检查域(DomainClass)的映射配置,尤其是id生成器的设置。3.达梦数据库可能需要显式创建序列,并在映射中指定序列名。解决方案:1.在达梦数据库中为每个需要自增id的表创建序列。例如:CREATESEQUENCEseq_nameSTARTWITH1INCREMENTBY1;2.在Grails的域中,通过mapping块指定id生成器为sequence,并给出序列名。示例:```groovyclassBook{Stringtitlestaticmapping={idgenerator:'sequence',params:[sequence:'seq_book']//指定达梦数据库中的序列名}}```3.如果之前使用Oracle时已经配置了序列,迁移后需要确保达梦数据库中存在同名的序列,或者修配置为达梦数据库中的序列名。4.另外,检查达梦数据库的JDBC驱动是否支持Grails的Hibernate序列生成策略。确保使用的JDBC驱动版本与Grails兼容。5.如果问题仍然存在,可以尝试在保存之前打印id的值,检查是否在保存前已经设置了id(可能是手动设置导致生成策略失效)。注意事项:-达梦数据库的序列语法与Oracle似,但创建序列的SQL可能需要调整(如达梦数据库的序列创建语句为:CREATESEQUENCE"序列名"STARTWITH1INCREMENTBY1CACHE20;)-在Grails的数据源配置(DataSource.groovy)中,确保方言(dialect)设置为达梦数据库的方言。如果没有,可能需要自定义方言。自定义方言(如果需要):在`grails-app/conf/spring/resources.groovy`中配置自定义方言(假设达梦数据库的方言为`com.dameng.DmDialect`):```groovybeans={dialect(com.dameng.DmDialect)//替换为实际的达梦数据库方言}```或者,在`application.yml`中配置(Grails3.x及以上):```yamldataSource:dialect:com.dameng.DmDialect```如果以上配置后问题仍然存在,请检查达梦数据库的JDBC驱动是否提供了正确的方言,或者联系达梦数据库技术支持获取正确的Hibernate方言。引用说明:关于Grailsid生成策略,可参考Grails官方文档[^1]。达梦数据库的序列使用可参考其官方文档[^2]。§§相关问题§§1.如何在达梦数据库中创建序列?2.Grails中如何配置多个数据源?3.如何自定义Hibernate方言?</think>### Grails 迁移到达梦数据库后 save 操作无法生成 ID 的解决方案 在 Grails 项目从 Oracle 迁移到达梦数据库后,`save()` 操作无法生成 ID 的问题通常由以下原因导致,以下是系统性解决方案: #### 1. **配置 ID 生成策略(关键步骤)** 达梦数据库需显式指定序列生成器: ```groovy // 在 Domain mapping 块中配置 static mapping = { id generator: 'sequence', params: [sequence: 'YOUR_SEQ_NAME'] // 替换为达梦序列名 } ``` - **原因**:达梦与 Oracle 序列机制差异,Oracle 默认使用 `sequence`,达梦需手动声明 - **操作**: 1. 在达梦创建序列:`CREATE SEQUENCE "YOUR_SEQ_NAME" START WITH 1 INCREMENT BY 1;` 2. 所有 Domain 需添加上述 `mapping` 配置 #### 2. **配置 Hibernate 方言** 在 `application.yml` 中设置正确方言: ```yaml dataSource: dialect: org.hibernate.dialect.DmDialect # 达梦专用方言 dbCreate: update url: jdbc:dm://localhost:5236/DB_NAME ``` - **验证**:检查是否误用 `OracleDialect` - **依赖**:确保包含达梦 JDBC 驱动(如 `com.dameng:DmJdbcDriver:8.x.x`) #### 3. **检查事务配置** ```groovy // 确保在服务层使用事务 @Transactional def saveEntity(Book book) { book.save(flush: true) // 必须带 flush:true } ``` - **典型错误**:无事务上下文导致 ID 未提交到数据库[^1] #### 4. **验证主键约束** ```sql -- 达梦表结构检查 SELECT column_name, data_type FROM user_tab_columns WHERE table_name='YOUR_TABLE' AND identity_column='YES'; ``` - **要求**:主键字段必须是 `IDENTITY` 型或关联序列 #### 5. **调试与日志** 在 `logback.groovy` 增加日志: ```groovy logger("org.hibernate.SQL", DEBUG, ["STDOUT"]) logger("org.hibernate.type.descriptor.sql", TRACE) ``` - **检查项**: - 是否生成 `INSERT` 语句 - 是否包含序列调用 `NEXTVAL('YOUR_SEQ')` --- ### 常见问题排查表 | 现象 | 解决方案 | |------|----------| | `save()` 返回 null ID | 检查事务配置和 `flush:true` | | 主键值未递增 | 验证序列创建及映射名称一致性 | | 启动时报方言错误 | 确认 `dm-dialect` 在依赖中 | | Oracle 遗留配置冲突 | 删除 `oracle` 相关插件和驱动 | > **迁移建议**:使用达梦的 **DTS 迁移工具** 转换 Oracle 表结构时,需勾选“保留序列对象”选项[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值