简体   繁体   English

Hibernate:模式验证:缺少表 - 区分大小写 Mysql 模式标识符变为大写

[英]Hibernate: Schema-validation: missing table - case-sensitive Mysql schema identifier turned upper-case

(context - migrating working Java server application from Spring/Hibernate 3 to 5) (上下文 - 将工作 Java 服务器应用程序从 Spring/Hibernate 3 迁移到 5)

Upon server start, the Hibernate validation fails with “ Schema-validation: missing table ”.服务器启动后,Hibernate 验证失败并显示“ Schema-validation: missing table ”。 The tables exist (the app is working with Hibernate 3)表格存在(应用程序正在使用 Hibernate 3)

The reason is the query [1] which fetches all tables from the DB informationSchema.原因是查询 [1] 从 DB informationSchema 中获取所有表。 The database name is 'myApp', but “WHERE (TABLE_SCHEMA = 'MYAPP')“ is queried.数据库名称为“myApp”,但查询“WHERE (TABLE_SCHEMA = 'MYAPP')”。 This leads to empty result set and “missing tables”.这会导致空结果集和“缺失表”。

The reason for that is the initial value of “unquotedCaseStrategy” [2] (IdentifierCaseStrategy.UPPER) which is left unchanged within “applyIdentifierCasing” method where all metaData.storesLowerCaseIdentifiers(),metaData.storesUpperCaseIdentifiers(),metaData.storesMixedCaseIdentifiers() return FALSE, because select @@lower_case_table_names called in MariaDbDatabaseMetaData#connection#getLowercaseTableNames() [4] method returns '0'.原因是“unquotedCaseStrategy”[2] (IdentifierCaseStrategy.UPPER) 的初始值在“applyIdentifierCasing”方法中保持不变,其中所有 metaData.storesLowerCaseIdentifiers()、metaData.storesUpperCaseIdentifiers()、metaData.storesMixedCaseIdentifiers() 返回 FALSE ,因为在 MariaDbDatabaseMetaData#connection#getLowercaseTableNames() [4] 方法中调用的 select @@lower_case_table_names 返回“0”。 This is the default value for Unix systems and as the JavaDoc [5] states, all table names and aliases and database names are compared in a case-sensitive manner.这是 Unix 系统的默认值,正如 JavaDoc [5] 所述,所有表名和别名以及数据库名称都以区分大小写的方式进行比较。

  • Hibernate = 5.6.7 Hibernate = 5.6.7
  • Java = jdk1.8.0_241 Java = jdk1.8.0_241
  • AppServer = wildfly-18.0.1.Final AppServer = wildfly-18.0.1.Final
  • DB = MariaDb 10.1数据库 = MariaDb 10.1
  • DB driver = mariadb-java-client-2.2.6.jar数据库驱动程序 = mariadb-java-client-2.2.6.jar

[1] [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') ORDER BY TABLE_TYPE, TABLE_SCHEMA, TABLE_NAME; 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 [2] org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder#unquotedCaseStrategy

[3] org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder#applyIdentifierCasing [3] org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder#applyIdentifierCasing

[4] org.mariadb.jdbc.MariaDbConnection#getLowercaseTableNames [4] org.mariadb.jdbc.MariaDbConnection#getLowercaseTableNames

[5] getLowercaseTableNames Javadoc: - Are table case sensitive or not. [5] getLowercaseTableNames Javadoc:- 表是否区分大小写。 Default Value: 0 (Unix), 1 (Windows), 2 (Mac OS X).默认值:0 (Unix)、1 (Windows)、2 (Mac OS X)。 If set to 0 (the default on Unix-based systems), table names and aliases and database names are compared in a case-sensitive manner.如果设置为 0(基于 Unix 的系统的默认值),表名和别名以及数据库名称将以区分大小写的方式进行比较。 If set to 1 (the default on Windows), names are stored in lowercase and not compared in a case-sensitive manner.如果设置为 1(Windows 上的默认值),名称将以小写形式存储并且不以区分大小写的方式进行比较。 If set to 2 (the default on Mac OS X), names are stored as declared, but compared in lowercase.如果设置为 2(Mac OS X 上的默认值),名称按声明存储,但以小写形式进行比较。

It seems to me there is an error in the applyIdentifierCasing method logic and the default (initial value) of the unquotedCaseStrategy strategy [2] should be IdentifierCaseStrategy.MIXED.在我看来,applyIdentifierCasing 方法逻辑中存在错误,unquotedCaseStrategy 策略 [2] 的默认值(初始值)应该是 IdentifierCaseStrategy.MIXED。

WORKAROUND: extend one of the Dialects in org.hibernate.dialect and @Override buildIdentifierHelper() method directly returning the IdentifierHelper instance (calling builder.build(); instead of super.buildIdentifierHelper(…) which would overwrite the config).变通方法:扩展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.

相关问题 Hibernate 5 模式验证:缺少带有 HBM 文件的表 - Hibernate 5 Schema-validation: missing table with HBM files Java Spring Hibernate Schema-Validation:缺少表 - Java Spring Hibernate Schema-Validation: Missing Table Hibernate + JPA:模式验证:缺少列 - Hibernate + JPA: Schema-validation: missing column 架构验证:缺少表 [hibernate_sequences] - Schema-validation: missing table [hibernate_sequences] Hibernate继承:模式验证:缺少列 - Hibernate inheritance: Schema-validation: missing column 使用Schema-validation验证除dbo结果以外的其他模式中的休眠访问表:缺少表 - Hibernate acessing table in schema other than dbo results with Schema-validation: missing table SqlServer2016,Hibernate 模式验证:缺少表,但表存在于数据库中 - SqlServer2016, Hibernate schema-validation: Missing table, but table exists in db 模式验证:使用Flyway的Hibernate生成的SQL代码缺少表[…]错误消息 - Schema-validation: missing table […] error message using flyway for a SQL code generated by Hibernate 获取 entityManageFactory 错误。 模式验证:缺少表 [hibernate_sequence] - Getting entityManageFactory error. Schema-validation: missing table [hibernate_sequence] 为什么Hibernate模式验证无法验证模式 - Why Hibernate schema-validation fail to validate schema
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM