当升级到Sping Boot 3和Hibernate 6时,似乎属性hibernate.hbm2ddl.schema_filter_provider
无法正常工作。我有一个SchemaFilterProvider的自定义实现,它将my_table
从验证中排除,我设置hibernate.hbm2ddl.schema_filter_provider
属性以使用它。我得到这个错误:org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [my_table]
调试后,我发现DefaultSchemaFilter.INSTANCE
正在使用,上面的属性没有被考虑:
验证在这里完成:
protected void validateTables(
Metadata metadata,
DatabaseInformation databaseInformation,
ExecutionOptions options,
ContributableMatcher contributableInclusionFilter,
Dialect dialect, Namespace namespace) {
final NameSpaceTablesInformation tables = databaseInformation.getTablesInformation( namespace );
for ( Table table : namespace.getTables() ) {
if ( options.getSchemaFilter().includeTable( table )
&& table.isPhysicalTable()
&& contributableInclusionFilter.matches( table ) ) {
validateTable(
table,
tables.getTableInformation( table ),
metadata,
options,
dialect
);
}
}
}
字符串options
在这里创建:
public static ExecutionOptions buildExecutionOptions(
final Map<String,Object> configurationValues,
final ExceptionHandler exceptionHandler) {
return buildExecutionOptions(
configurationValues,
DefaultSchemaFilter.INSTANCE,
exceptionHandler
);
}
型
这意味着DefaultSchemaFilter.INSTANCE
将始终处于使用状态。
Hibernate有一个没有响应的公开bug:https://hibernate.atlassian.net/browse/HBX-2476
如何将my_table
从验证中排除?
1条答案
按热度按时间ddrv8njm1#
自从https://hibernate.atlassian.net/browse/HBX-2476被打开以来已经快一年了,它仍然没有解决。我要分享一个讨厌的解决方法,至少对我有用,直到bug被修复。
临时解决方案
使用反射,设置(静态final)
DefaultSchemaFilter.INSTANCE
的值以引用在早期Hibernate版本中使用的自定义SchemaFilter
的示例。这样,当Hibernate将使用“硬编码”DefaultSchemaFilter.INSTANCE
作为过滤器时,它实际上将使用我们的自定义过滤器实现。请注意,自定义实现extends DefaultSchemaFilter
。例如,假设我们有这样一个自定义实现,它跳过了PostgreSQL临时表的验证:
字符串
我们需要设置
DefaultSchemaFilter.INSTANCE = CustomSchemaFilter.INSTANCE
。反射代码的具体实现取决于Java版本。对于Java 17,基于https://stackoverflow.com/a/56043252/9061851,我使用了以下代码:
型
但是,这需要将
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
添加到JVM运行参数中。这段代码应该在Hibernate运行其验证之前调用。最简单的选择是在加载Sping Boot 之前从
main()
调用它。提示:这只是一个临时的解决方案。