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

JPA @Entity映射无ID列Oracle表遇ORA-00904错误的解决咨询

解决JPA实体映射无ID列Oracle表的问题

错误原因

你添加@Id + GenerationType.IDENTITY后报错,是因为JPA会根据这个注解生成查询去读取ID列,但你的my_table根本没有这个列,所以Oracle抛出ORA-00904(标识符无效)错误。JPA要求所有实体必须有主键(@Id标注),不能省略,所以可从以下两种方向解决:


方案1:使用现有列作为复合主键

如果你的my_table中,DATE和SUMTYPE的组合是唯一的(无重复行),可以把这两个字段设为复合主键,无需修改数据库表结构。

步骤1:创建主键类

这个类必须实现Serializable,包含要作为主键的字段,并正确重写equals()和hashCode():

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CashFlowPK implements Serializable {
    private LocalDate date;
    private String sumType;
}

步骤2:修改实体类

用@IdClass指定主键类,并给每个主键字段添加@Id注解:

@Entity
@Table(name = "my_table")
@Data
@NoArgsConstructor
@AllArgsConstructor
@IdClass(CashFlowPK.class) // 指定主键类
public class CashFlowTrainingData {

    @Id // 标记为主键字段
    @Column(name = "DATE")
    private LocalDate date;

    @Id // 标记为主键字段
    @Column(name = "SUMTYPE")
    private String sumType;

    @Column(name = "SUM")
    private Double sum;
}

方案2:给数据库表添加ID列(推荐,若允许修改表结构)

如果可以修改数据库表,添加一个自增ID列是最省心的方案,符合JPA单主键的常规用法。

步骤1:给Oracle表添加自增ID列

  • Oracle 12c及以上支持IDENTITY自增列,执行SQL:
ALTER TABLE my_table ADD id NUMBER GENERATED ALWAYS AS IDENTITY START WITH 1 INCREMENT BY 1;
  • Oracle 11g及以下版本,需手动创建序列和触发器:
-- 创建序列
CREATE SEQUENCE my_table_seq START WITH 1 INCREMENT BY 1;

-- 创建触发器,插入时自动赋值ID
CREATE OR REPLACE TRIGGER my_table_trigger
BEFORE INSERT ON my_table
FOR EACH ROW
BEGIN
  SELECT my_table_seq.NEXTVAL INTO :NEW.id FROM DUAL;
END;
/

步骤2:修改实体类对应ID注解

  • Oracle 12c+用IDENTITY策略:
@Entity
@Table(name = "my_table")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CashFlowTrainingData {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "DATE")
    private LocalDate date;

    @Column(name = "SUMTYPE")
    private String sumType;

    @Column(name = "SUM")
    private Double sum;
}
  • Oracle 11g及以下用序列策略:
@Entity
@Table(name = "my_table")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CashFlowTrainingData {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_table_seq")
    @SequenceGenerator(name = "my_table_seq", sequenceName = "MY_TABLE_SEQ", allocationSize = 1)
    private Long id;

    @Column(name = "DATE")
    private LocalDate date;

    @Column(name = "SUMTYPE")
    private String sumType;

    @Column(name = "SUM")
    private Double sum;
}

内容的提问来源于stack exchange,提问作者Павлюченко Антон

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 10:53:35