EF Core中Oracle序列需用HasDefaultValueSql或HasComputedColumnSql配置,不可用JPA注解;MyBatis中@SequenceGenerator仅为标记,须配合@SelectKey或<selectKey>使用,且keyProperty须与字段名严格一致。
Oracle序列在EF Core里根本不能用@SequenceGenerator
ef core没有@sequencegenerator这个注解——那是jpa/hibernate的语法,直接照搬会编译报错或完全不生效。ef core生成主键靠的是valuegeneratedonadd()配合数据库函数,不是靠java那一套注解驱动。
常见错误现象:InvalidOperationException: The property 'Id' has a value generator but the entity type is not configured to use it,或者插入时主键为0/NULL。
- 必须在
OnModelCreating里显式配置:用HasDefaultValueSql("SEQUENCE_NAME.NEXTVAL")(Oracle 12c+)或HasComputedColumnSql("SEQUENCE_NAME.NEXTVAL")(旧版) - 别用
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]——Oracle没IDENTITY列,它只会让你插入失败 - 确保序列存在且当前用户有
SELECT权限,否则运行时报ORA-00942: table or view does not exist
MyBatis中@SequenceGenerator只在@SelectKey或XML里起作用
MyBatis的@SequenceGenerator本身不触发任何行为,它只是个标记;真正干活的是@SelectKey或XML里的<selectKey>标签。很多人加了注解但没配@SelectKey,结果主键还是null。
使用场景:插入前需要从序列取值,且不希望依赖数据库默认值(比如要兼容H2测试库)。
-
@SelectKey必须加在@Insert方法上,before = true,resultType = long.class - SQL写法必须是
SELECT SEQUENCE_NAME.NEXTVAL FROM DUAL,少FROM DUAL在Oracle里直接报错 - 如果用了
useGeneratedKeys = true,它会忽略序列,转而尝试用RETURNING子句——但Oracle旧驱动不支持,容易静默失败
EF Core + Oracle Provider要注意驱动版本和方言差异
Oracle官方提供的Oracle.EntityFrameworkCore和第三方Devart.Data.Oracle.EFCore对序列支持方式不同,参数稍有偏差就导致生成SQL出错。
性能影响:每次插入都走一次NEXTVAL查询,比自增ID多一次 round-trip;高并发下可能成为瓶颈。
- Oracle EF Core Provider 7.x 要求数据库兼容12.1+,低于此版本需降级到5.x并改用
HasComputedColumnSql -
HasDefaultValueSql("MY_SEQ.NEXTVAL")生成的INSERT语句不含主键字段,但如果你手动赋值了Id,EF Core会把它当普通字段塞进去,覆盖序列值 - 迁移脚本里不会自动创建序列,得手写
Sql("CREATE SEQUENCE ..."),否则部署环境直接炸
MyBatis XML里<selectKey>的keyProperty写错就白忙活
这是最常被忽略的一环:keyProperty必须和实体类字段名完全一致(区分大小写),且不能带this.或entity.前缀。写成keyProperty="id"但实体里是private Long Id;,值就进不去。
错误现象:日志显示查到了序列值,但对象ID仍是null或0。
- Oracle要求
order="BEFORE",resultType="long",statementType="STATEMENT"(不能用PREPARED) - 如果实体用Lombok的
@Data,确保setId()方法存在且可访问;私有字段+无setter会导致设值失败 - 批量插入时
<selectKey>只执行一次,不能用于批量主键生成——得换foreach+ 单条插入,或改用数据库端的INSERT ALL
序列值本身不可回滚,哪怕事务失败,NEXTVAL也已递增。这点在压测或异常频繁的场景里,容易让序列“跳号”看起来很奇怪,但其实是设计使然,不是bug。

















