2. 标准命名策略
Hibernate 6 默认使用标准命名策略。它会根据实体名称和列名生成标准化的序列名称。例如,对于实体 Person
和列 id
,序列名将是 person_seq
。
✅ 配置方式:在 application.properties
中添加以下配置:
spring.jpa.properties.hibernate.id.db_structure_naming_strategy=standard
来看一个基础实体类示例:
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String name;
// setters and getters
}
使用标准策略时,Hibernate 会自动创建名为 person_seq
的序列:
Hibernate:
create table person (
id bigint not null,
name varchar(255),
primary key (id)
)
Hibernate:
create sequence person_seq start with 1 increment by 50
⚠️ 关键点:标准策略默认使用较大的增量值(如 50),这是为了优化批量操作,减少数据库调用次数。
插入记录时,Hibernate 会使用 person_seq
生成主键:
Hibernate:
select next value for person_seq
Hibernate:
insert
into person (name,id)
values (?,?)
自定义表名:可以通过 @Table
注解覆盖表映射,序列名会同步更新:
@Entity
@Table(name = "my_person_table")
public class Person {
// ...
}
此时序列名变为 my_person_table_seq
:
Hibernate:
create table my_person_table (
id bigint not null,
name varchar(255),
primary key (id)
)
Hibernate:
create sequence my_person_table_seq start with 1 increment by 50
3. 遗留命名策略
此策略与标准策略类似,但使用遗留命名约定或生成器名称。默认情况下,所有实体共享名为 hibernate_sequence
的序列。
✅ 配置方式:
spring.jpa.properties.hibernate.id.db_structure_naming_strategy=legacy
使用 Person
实体时,Hibernate 会创建:
Hibernate:
create table person (
id bigint not null,
name varchar(255),
primary key (id)
)
Hibernate:
create sequence hibernate_sequence start with 1 increment by 1
❌ 与标准策略的区别:默认增量值为 1(而非 50),每次只递增 1。
插入记录时使用共享序列:
Hibernate:
select next value for hibernate_sequence
Hibernate:
insert
into person (name,id)
values (?,?)
自定义序列:即使使用 @Table
修改表名,序列名仍为 hibernate_sequence
。但可通过 @SequenceGenerator
自定义:
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "person_custom_seq")
@SequenceGenerator(name = "person_custom_seq", sequenceName = "person_custom_seq", allocationSize = 10)
private Long id;
此时生成的序列名为 person_custom_seq
,增量为 10:
Hibernate:
create sequence person_custom_seq start with 1 increment by 10
💡 适用场景:主要用于兼容旧版 Hibernate,避免破坏现有系统。
4. 单一命名策略
Hibernate 6 新增此策略,为同一 schema 下的所有实体使用统一序列名(与遗留策略类似,所有实体共享 hibernate_sequence
)。
✅ 配置方式:
spring.jpa.properties.hibernate.id.db_structure_naming_strategy=single
考虑两个实体 Person
和 Book
:
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String title;
// setters and getters
}
Hibernate 只创建一个共享序列:
Hibernate:
create table book (...)
Hibernate:
create table person (...)
Hibernate:
create sequence hibernate_sequence start with 1 increment by 1
插入记录验证:
Person person = new Person();
person.setName("John Doe");
personRepository.save(person);
Book book = new Book();
book.setTitle("Baeldung");
bookRepository.save(book);
List<Person> personList = personRepository.findAll();
List<Book> bookList = bookRepository.findAll();
assertEquals((long)1,(long) personList.get(0).getId());
assertEquals((long)2, (long) bookList.get(0).getId());
✅ 结果:
Person
获得 ID 1,Book
获得 ID 2,证明使用同一序列生成器。
5. 自定义命名策略
通过实现 ImplicitDatabaseObjectNamingStrategy
接口,可以完全自定义序列命名规则。
✅ 实现步骤:
创建自定义策略类:
public class CustomSequenceNamingStrategy implements ImplicitDatabaseObjectNamingStrategy { @Override public QualifiedName determineSequenceName(Identifier catalogName, Identifier schemaName, Map<?, ?> map, ServiceRegistry serviceRegistry) { JdbcEnvironment jdbcEnvironment = serviceRegistry.getService(JdbcEnvironment.class); String seqName = ((String) map.get("jpa_entity_name")).concat("_custom_seq"); return new QualifiedSequenceName( catalogName, schemaName, jdbcEnvironment.getIdentifierHelper().toIdentifier(seqName)); } // 其他方法... }
配置 Hibernate 使用自定义策略:
spring.jpa.properties.hibernate.id.db_structure_naming_strategy=com.example.CustomSequenceNamingStrategy
生成的序列名将遵循自定义规则(如 person_custom_seq
):
Hibernate:
create sequence person_custom_seq start with 1 increment by 50
替代方案:PhysicalNamingStrategy
可实现更全面的命名规则(不仅限于序列):
public class CustomPhysicalNamingStrategy extends DelegatingPhysicalNamingStrategy {
@Override
public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment context) {
return new Identifier(name.getText() + "_custom_seq", name.isQuoted());
}
// 其他表/列命名方法...
}
6. 总结
本文详细探讨了 Hibernate 6 的序列命名策略:
- 标准策略:基于实体名生成序列(如
person_seq
),默认增量 50 - 遗留策略:所有实体共享
hibernate_sequence
,增量 1,兼容旧版 - 单一策略:类似遗留策略,统一使用
hibernate_sequence
- 自定义策略:通过
ImplicitDatabaseObjectNamingStrategy
或PhysicalNamingStrategy
实现完全控制
💡 踩坑提示:升级 Hibernate 6 时,默认策略变更可能导致序列名冲突,建议显式配置策略。
完整示例代码可在 GitHub 获取。