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

Hibernate使用Oracle序列作为实体ID调用save方法抛出PropertyAccessException异常

问题根因

该异常是典型的Oracle NUMBER类型与Java Long类型映射不匹配导致的伪错误提示。Oracle序列返回的默认值类型是BigDecimal,如果你的MY_ID字段在数据库中没有指定明确的精度,Hibernate默认会将无精度的NUMBER类型映射为BigDecimal,反射赋值给Long类型的myid字段时类型转换失败,异常被包装后就会出现「无法给Long字段赋值null」的错误提示,实际和null值无关。

可行解决方案

方案1:明确指定ID字段的映射精度(推荐)

修改实体类的@Column注解,明确指定字段的数据库类型精度,让Hibernate直接将映射类型匹配为Long:

@Id
@SequenceGenerator(name="seqName", sequenceName="myschema.mysequence",allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seqName") 
@Column(name = "MY_ID", columnDefinition = "NUMBER(19,0)") // 新增columnDefinition配置,19为Long类型最大支持精度
private Long myid;

配置后Hibernate会自动完成类型转换,反射赋值不会再报错,直接调用session.save()即可正常返回生成的主键。

方案2:原生SQL插入返回主键(适配现有逻辑)

如果你需要继续用原生SQL插入,可以利用Oracle的RETURNING子句直接返回生成的主键,无需提前查询序列:

Query query = session.createNativeQuery("INSERT INTO myschema.MYTABLE (MY_ID, someotherfields)" 
    + " VALUES (myschema.mysequence.nextval, :someotherfieldvalues) RETURNING MY_ID");
// 绑定业务字段参数
query.setParameter("someotherfieldvalues", yourValue);
// 执行插入并获取返回的主键
Long generatedId = ((BigDecimal) query.getSingleResult()).longValue();

方案3:批量插入性能优化

如果需要批量插入数千条数据,在Hibernate配置文件中添加如下参数即可大幅提升save()方法的批量插入性能:

# 每100条SQL做一次批量提交,可根据实际场景调整大小
hibernate.jdbc.batch_size=100
hibernate.order_inserts=true
hibernate.jdbc.batch_versioned_data=true

配置开启后批量插入性能相比单次查询序列再插入可提升10倍以上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:15:01