【问题标题】:Spring JPA + Oracle 12 C Schema Validation IssueSpring JPA + Oracle 12 C 模式验证问题
【发布时间】:2021-05-20 05:40:54
【问题描述】:

在“Spring Boot + JPA + Oracle 12C”中面临模式验证问题。这与 Postgres 数据库一样工作。

进一步调试后,我发现来自类InformationExtractorJdbcDatabaseMetaDataImpl 的以下代码sn-p 返回一个空表列表,因为hibernate 尝试create 表而不是update现有表。

ResultSet resultSet = 
     extractionContext.getJdbcDatabaseMetaData()
                      .getTables(catalogFilter,
                                 schemaFilter,
                                 "%",
                                 tableTypes);   

Datasource/TransactionManager 等配置

@Primary
@Bean(name = "first-db")
public DataSource firstDataSource() {
    HikariDataSource hikariDS = new HikariDataSource();
    hikariDS.setJdbcUrl(env.getProperty("primary.datasource.jdbc-url"));
    hikariDS.setUsername(env.getProperty("primary.datasource.username"));
    hikariDS.setPassword(env.getProperty("primary.datasource.password"));
    hikariDS.setDriverClassName(env.getProperty("primary.datasource.driver-class-name"));      
    
    hikariDS.setConnectionTimeout(env.getProperty("primary.datasource.hikari.connection-timeout", Integer.class));
    hikariDS.setIdleTimeout(env.getProperty("primary.datasource.hikari.idle-timeout", Integer.class));
    hikariDS.setMaxLifetime(env.getProperty("primary.datasource.hikari.max-lifetime", Integer.class));
    hikariDS.setMinimumIdle(env.getProperty("primary.datasource.hikari.minimum-idle", Integer.class));      
    hikariDS.setMaximumPoolSize(env.getProperty("primary.datasource.hikari.maximum-pool-size", Integer.class));     
    hikariDS.setPoolName(env.getProperty("primary.datasource.hikari.pool-name", String.class));
    
    return hikariDS;
}


@Primary
@Bean(name = "firstEntityManagerFactory")
@Qualifier("primary")
public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory() {

    LocalContainerEntityManagerFactoryBean entityManagerFactory =  new LocalContainerEntityManagerFactoryBean();

    entityManagerFactory.setDataSource(firstDataSource());

    // Classpath scanning of @Component, @Service, etc annotated class
    entityManagerFactory.setPackagesToScan(
            env.getProperty("first.entitymanager.packagesToScan"));

    // Vendor adapter
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setShowSql(Boolean.getBoolean(env.getProperty("first.hibernate.show_sql")));
    vendorAdapter.setDatabasePlatform(env.getProperty("first.hibernate.dialect"));
    vendorAdapter.setDatabase(Database.ORACLE); //Database.POSTGRESQL

    // Hibernate properties
    Properties jpaProperties = new Properties();
    jpaProperties.setProperty("hibernate.dialect", env.getProperty("first.hibernate.dialect"));
    jpaProperties.setProperty("hibernate.show_sql", env.getProperty("first.hibernate.show_sql"));
    jpaProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("first.hibernate.hbm2ddl.auto"));
    jpaProperties.setProperty("database-platform", env.getProperty("first.hibernate.dialect"));
    jpaProperties.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false");

    jpaProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
    jpaProperties.setProperty("spring.jpa.hibernate.ddl-auto", "update");
    jpaProperties.setProperty("hibernate.ddl-auto", "update");

    entityManagerFactory.setJpaVendorAdapter(vendorAdapter);
    entityManagerFactory.setJpaProperties(jpaProperties);
    entityManagerFactory.setPersistenceUnitName("EWS-Primary-DB");

    return entityManagerFactory;
}

@Primary
@Bean(name = "firstTransactionManager")
public PlatformTransactionManager firstTransactionManager() {       
    JpaTransactionManager tm = new JpaTransactionManager();
    tm.setEntityManagerFactory(firstEntityManagerFactory().getObject());

    return tm;
}

框架代码 (GroupSchemaMigratorImpl.java)

final NameSpaceTablesInformation tables = existingDatabase.getTablesInformation( namespace );
for ( Table table : namespace.getTables() ) {
    if ( schemaFilter.includeTable( table ) && table.isPhysicalTable() ) {
        checkExportIdentifier( table, exportIdentifiers );
        final TableInformation tableInformation = tables.getTableInformation( table );
        if ( tableInformation == null ) {
            createTable( table, dialect, metadata, formatter, options, targets );
        }
        else if ( tableInformation != null && tableInformation.isPhysicalTable() ) {
            tablesInformation.addTableInformation( tableInformation );
            migrateTable( table, tableInformation, dialect, metadata, formatter, options, targets );
        }
    }
}

【问题讨论】:

  • 你能告诉我们你是如何配置数据源 XML 或纯 bean 配置的吗?

标签: spring spring-boot jpa oracle12c


【解决方案1】:

hibernate.hbm2ddl.auto 在创建 SessionFactory 时自动验证模式 DDL 或将其导出到数据库:

update:更新架构,如果不存在则创建一个新架构

create :创建架构,销毁以前的数据

create-drop :当应用程序停止或 SessionFactory 显式关闭时删除架构。

validate:验证架构,不对数据库进行任何更改,这是推荐用于生产环境的方法。

我没有注意到hibernate.hbm2ddl.auto 的值,因为您的问题中没有定义first.hibernate.hbm2ddl.auto,无论如何您必须将其更改为validateupdate

只需将hibernate.hbm2ddl.auto 的值更改为validate

【讨论】:

  • 我无法添加内容应用程序属性。所有这些属性都在那里定义。
  • @VishalPatil 确保表存在并将first.hibernate.hbm2ddl.auto 更改为validate,因为update 将在表不存在时创建表
  • 表已存在于数据库中。当我设置正确的 first.hibernate.hbm2ddl.auto = validate 时,出现以下错误 org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [external_rating_error_stg]
  • @VishalPatil 它的另一个线程,看看这里:stackoverflow.com/questions/44479406/…
  • 属性“hibernate.temp.use_jdbc_metadata_defaults”设置为false,这导致了整个问题。通过以下更改解决了问题 hibernate.temp.use_jdbc_metadata_defaults=true
【解决方案2】:

属性“hibernate.temp.use_jdbc_metadata_defaults”在我的代码中设置为 false,这导致了整个问题。问题已通过以下更改解决 hibernate.temp.use_jdbc_metadata_defaults=true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 2012-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    相关资源
    最近更新 更多