Spring Data JPA自动生成表时列顺序混乱的解决办法(Hibernate 6.2 +)
1. 创建你的自定义排序策略类
需要创建一个 Java 类,实现 org.hibernate.boot.model.relational.ColumnOrderingStrategy
接口。 因为这里只排序创建表的字段顺序,这里继承原有默认的方式 org.hibernate.boot.model.relational.ColumnOrderingStrategyStandard
类,重写 orderTableColumns
方法。
package ink.metoo.gude.hibernate.strategy;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.model.relational.ColumnOrderingStrategyStandard;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Table;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SimpleColumnOrderingStrategy extends ColumnOrderingStrategyStandard {
@Override
public List<Column> orderTableColumns(Table table, Metadata metadata) {
return table.getColumns().stream()
.sorted(new SimpleColumnComparator(metadata))
.collect(Collectors.toList());
}
private static class SimpleColumnComparator extends ColumnOrderingStrategyStandard.ColumnComparator {
// 排在最末尾的字段
private static final String[] END_COLUMN = {"last_modified_date", "create_date"};
public SimpleColumnComparator(Metadata metadata) {
super(metadata);
}
@Override
public int compare(Column o1, Column o2) {
// identity column first
if (o1.isIdentity() && !o2.isIdentity()) return 0;
if (o1.isIdentity()) return -1;
if (o2.isIdentity()) return 1;
// end column last
boolean o1Contains = Arrays.asList(END_COLUMN).contains(o1.getName());
boolean o2Contains = Arrays.asList(END_COLUMN).contains(o2.getName());
if (o1Contains && o2Contains) return 0;
if (o1Contains) return 1;
if (o2Contains) return -1;
return super.compare(o1, o2);
}
}
}
1.1. 关于排序逻辑的说明
orderTableColumns
方法接收一个 Table 对象和该表中的Column
对象列表。- 你需要返回一个排序后的
Column
对象列表。 - 实现自定义排序逻辑的关键是使用
java.util.Comparator
。在Comparator
内部,你可以根据Column
对象的属性(如getName()
)来定义排序规则。 - 注意: 像“保持 JPA 实体中字段的声明顺序”这种需求,单纯通过
ColumnOrderingStrategy
实现会非常困难,甚至不可能。因为 Hibernate 在构建其内部元数据模型时,已经失去了 Java 源代码中字段的声明顺序信息。ColumnOrderingStrategy 只能对 Hibernate 已经识别到的列进行排序,而不是改变它识别列的方式。
2. 在 Spring Boot 配置中引用它
spring:
jpa:
properties:
hibernate:
column_ordering_strategy: ink.metoo.gude.hibernate.strategy.SimpleColumnOrderingStrategy
在你的 application.properties
或 application.yml
文件中,将 spring.jpa.properties.hibernate.column_ordering_strategy
属性设置为你刚刚创建的自定义类的完全限定名。
2.1. 注意
spring.jpa.properties.hibernate.column_ordering_strategy
这个属性用于配置 Hibernate 6.2 及更高版本中列的排序策略。它允许你自定义 Hibernate 在生成数据库 DDL 时表中列的物理顺序。
3. 测试与验证
- 启动你的 Spring Boot 应用程序。
- 确保
spring.jpa.hibernate.ddl-auto
被设置为create
或create-drop
,这样 Hibernate 会重新生成 Schema。 - 使用数据库客户端工具连接到你的数据库,并查看由
Hibernate
生成的表的 DDL (Data Definition Language) 或者表结构,验证列的顺序是否按照你的 CustomColumnOrderingStrategy 中的定义进行了排序。
评论
其他文章