@Id 和 @GeneratedValue 必须配合使用以定义主键:@Id 标识唯一主键字段,类型推荐 Long 等包装类;@GeneratedValue 通过 strategy 指定 IDENTITY、SEQUENCE、TABLE 或 AUTO 策略,并可借助 generator 属性复用 @SequenceGenerator 或 @TableGenerator。

@Id 和 @GeneratedValue 是 JPA 中定义主键的核心注解,必须配合使用才能让框架正确生成和管理主键值。
主键字段必须标注 @Id
一个实体类只能有一个字段用 @Id 标记,它告诉 JPA 这个字段对应数据库表的主键列。不加 @Id,JPA 不会识别该字段为主键,持久化操作会失败。
- 可以放在字段上(最常见),也可以放在 getter 方法上(需保持整个类统一)
- 类型通常为 Long、Integer 或 String,但推荐使用包装类型(如 Long)以支持 null 判断
- 若主键是复合主键,需改用 @EmbeddedId 或 @IdClass,不能只靠 @Id
@GeneratedValue 指定生成方式
它必须与 @Id 同时出现,单独使用无效。核心是通过 strategy 属性选择生成策略:
- GenerationType.IDENTITY:依赖数据库自增(如 MySQL 的 AUTO_INCREMENT)。插入时数据库自动赋值,JPA 读回生成的 ID。MySQL、PostgreSQL 支持,Oracle 不支持。
- GenerationType.SEQUENCE:借助数据库序列(如 Oracle 的 SEQUENCE)。需配合 @SequenceGenerator 声明序列名和参数。Oracle、PostgreSQL 支持,MySQL 原生不支持。
- GenerationType.TABLE:用一张专用表模拟序列(如 hibernate_sequences),由 JPA 控制读写。跨数据库兼容性好,但有额外 I/O 开销。
- GenerationType.AUTO(默认):JPA 自动选策略——优先用 IDENTITY(如果数据库支持),否则尝试 SEQUENCE,最后 fallback 到 TABLE。开发省心,但行为依赖底层数据库。
generator 属性用于复用命名生成器
当需要精细控制序列或表行为时,可定义独立生成器:
立即学习“Java免费学习笔记(深入)”;
- 用 @SequenceGenerator(name="user_seq", sequenceName="user_id_seq") 定义序列生成器
- 在 @GeneratedValue 中引用:
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq") - 同理,@TableGenerator 配合 generator 使用,适用于 TABLE 策略
- generator 名称必须唯一且匹配,否则启动报错
常见配置示例
MySQL 场景下最常用:
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ...
}
Oracle 或多数据库兼容场景可选:
@Entity
@SequenceGenerator(name = "user_gen", sequenceName = "user_seq", allocationSize = 1)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_gen")
private Long id;
// ...
}
不复杂但容易忽略细节。


















