[英]Hibernate: Schema-validation: missing table - case-sensitive Mysql schema identifier turned upper-case
(上下文 - 将工作 Java 服务器应用程序从 Spring/Hibernate 3 迁移到 5)
服务器启动后,Hibernate 验证失败并显示“ Schema-validation: missing table ”。 表格存在(应用程序正在使用 Hibernate 3)
原因是查询 [1] 从 DB informationSchema 中获取所有表。 数据库名称为“myApp”,但查询“WHERE (TABLE_SCHEMA = 'MYAPP')”。 这会导致空结果集和“缺失表”。
原因是“unquotedCaseStrategy”[2] (IdentifierCaseStrategy.UPPER) 的初始值在“applyIdentifierCasing”方法中保持不变,其中所有 metaData.storesLowerCaseIdentifiers()、metaData.storesUpperCaseIdentifiers()、metaData.storesMixedCaseIdentifiers() 返回 FALSE ,因为在 MariaDbDatabaseMetaData#connection#getLowercaseTableNames() [4] 方法中调用的 select @@lower_case_table_names 返回“0”。 这是 Unix 系统的默认值,正如 JavaDoc [5] 所述,所有表名和别名以及数据库名称都以区分大小写的方式进行比较。
[1]
SELECT TABLE_SCHEMA TABLE_CAT, NULL TABLE_SCHEM, TABLE_NAME, IF(TABLE_TYPE='BASE TABLE', 'TABLE', TABLE_TYPE) as TABLE_TYPE, TABLE_COMMENT REMARKS, NULL TYPE_CAT, NULL TYPE_SCHEM, NULL TYPE_NAME, NULL SELF_REFERENCING_COL_NAME, NULL REF_GENERATION FROM INFORMATION_SCHEMA.TABLES WHERE ( TABLE_SCHEMA = 'MYAPP') AND (TABLE_NAME LIKE '%') AND TABLE_TYPE IN ('BASE TABLE','VIEW') 按 TABLE_TYPE、TABLE_SCHEMA、TABLE_NAME 排序;
[2] org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder#unquotedCaseStrategy
[3] org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder#applyIdentifierCasing
[4] org.mariadb.jdbc.MariaDbConnection#getLowercaseTableNames
[5] getLowercaseTableNames Javadoc:- 表是否区分大小写。 默认值:0 (Unix)、1 (Windows)、2 (Mac OS X)。 如果设置为 0(基于 Unix 的系统的默认值),表名和别名以及数据库名称将以区分大小写的方式进行比较。 如果设置为 1(Windows 上的默认值),名称将以小写形式存储并且不以区分大小写的方式进行比较。 如果设置为 2(Mac OS X 上的默认值),名称按声明存储,但以小写形式进行比较。
在我看来,applyIdentifierCasing 方法逻辑中存在错误,unquotedCaseStrategy 策略 [2] 的默认值(初始值)应该是 IdentifierCaseStrategy.MIXED。
变通方法:扩展org.hibernate.dialect
和@Override buildIdentifierHelper()
方法中的一种方言,直接返回 IdentifierHelper 实例(调用 builder.build(); 而不是 super.buildIdentifierHelper(...) 会覆盖配置)。
public class MySQL5InnoDBDialectEx extends MySQL55Dialect {
public MySQL5InnoDBDialectEx() {
super();
registerColumnType(Types.BIT, "tinyint(1)");
}
@Override
public IdentifierHelper buildIdentifierHelper(IdentifierHelperBuilder builder, DatabaseMetaData dbMetaData) throws SQLException {
// Copied from org.hibernate.dialect.Dialect#buildIdentifierHelper..
builder.applyReservedWords(dbMetaData);
builder.applyReservedWords(AnsiSqlKeywords.INSTANCE.sql2003());
builder.setUnquotedCaseStrategy(IdentifierCaseStrategy.MIXED);
builder.setQuotedCaseStrategy(IdentifierCaseStrategy.MIXED);
// DO NOT USE >>return super.buildIdentifierHelper( builder, dbMetaData );<<
// as is normally done in the superClasses, because it overwrites the Quoted/UnquotedCaseStrategy (that is a bug..)
return builder.build();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.