当数据库中有很多对象时,Spring Boot无法从Hibernate启动

时间:2018-08-03 06:08:22

标签: hibernate spring-boot

我的Spring引导版本是2.0.3

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.3.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

当数据库中有成千上万个表,索引,序列时,应用程序引导过程将花费数小时。

经过一番调查,我发现它在创建EntityManagerFactory时试图检索数据库架构信息。这是初始化期间的3个不同的调用栈。

            SequenceInformationExtractorLegacyImpl.extractMetadata(ExtractionContext) line: 46  
        DatabaseInformationImpl.initializeSequences() line: 65  
        DatabaseInformationImpl.<init>(ServiceRegistry, JdbcEnvironment, DdlTransactionIsolator, Namespace$Name) line: 59   
        Helper.buildDatabaseInformation(ServiceRegistry, DdlTransactionIsolator, Namespace$Name) line: 132  
        GroupedSchemaMigratorImpl(AbstractSchemaMigrator).doMigration(Metadata, ExecutionOptions, TargetDescriptor) line: 96    
        SchemaManagementToolCoordinator.performDatabaseAction(Action, Metadata, SchemaManagementTool, ServiceRegistry, ExecutionOptions) line: 183  
        SchemaManagementToolCoordinator.process(Metadata, ServiceRegistry, Map, DelayedDropRegistry) line: 72   
        SessionFactoryImpl.<init>(MetadataImplementor, SessionFactoryOptions) line: 312 
        SessionFactoryBuilderImpl.build() line: 462 
        EntityManagerFactoryBuilderImpl.build() line: 892   
        SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo, Map) line: 57    
        LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory() line: 365 
        LocalContainerEntityManagerFactoryBean(AbstractEntityManagerFactoryBean).buildNativeEntityManagerFactory() line: 390    
        LocalContainerEntityManagerFactoryBean(AbstractEntityManagerFactoryBean).afterPropertiesSet() line: 377 
        LocalContainerEntityManagerFactoryBean.afterPropertiesSet() line: 341   
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeInitMethods(String, Object, RootBeanDefinition) line: 1767 
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1704    
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 581 
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 503   
        DefaultListableBeanFactory(AbstractBeanFactory).lambda$doGetBean$0(String, RootBeanDefinition, Object[]) line: 317  
        214649627.getObject() line: not available   
        DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 222   
        DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 315    
        DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 199   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).getBean(String) line: 1089   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 859   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).refresh() line: 550  
        AnnotationConfigServletWebServerApplicationContext(ServletWebServerApplicationContext).refresh() line: 140  
        SpringApplication.refresh(ApplicationContext) line: 759 
        SpringApplication.refreshContext(ConfigurableApplicationContext) line: 395  
        SpringApplication.run(String...) line: 327  


        InformationExtractorJdbcDatabaseMetaDataImpl.processTableResults(ResultSet) line: 393   
        InformationExtractorJdbcDatabaseMetaDataImpl.getTables(Identifier, Identifier) line: 336    
        DatabaseInformationImpl.getTablesInformation(Namespace) line: 120   
        GroupedSchemaMigratorImpl.performTablesMigration(Metadata, DatabaseInformation, ExecutionOptions, Dialect, Formatter, Set<String>, boolean, boolean, Set<Identifier>, Namespace, GenerationTarget[]) line: 65   
        GroupedSchemaMigratorImpl(AbstractSchemaMigrator).performMigration(Metadata, DatabaseInformation, ExecutionOptions, Dialect, GenerationTarget...) line: 207 
        GroupedSchemaMigratorImpl(AbstractSchemaMigrator).doMigration(Metadata, ExecutionOptions, TargetDescriptor) line: 114   
        SchemaManagementToolCoordinator.performDatabaseAction(Action, Metadata, SchemaManagementTool, ServiceRegistry, ExecutionOptions) line: 183  
        SchemaManagementToolCoordinator.process(Metadata, ServiceRegistry, Map, DelayedDropRegistry) line: 72   
        SessionFactoryImpl.<init>(MetadataImplementor, SessionFactoryOptions) line: 312 
        SessionFactoryBuilderImpl.build() line: 462 
        EntityManagerFactoryBuilderImpl.build() line: 892   
        SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo, Map) line: 57    
        LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory() line: 365 
        LocalContainerEntityManagerFactoryBean(AbstractEntityManagerFactoryBean).buildNativeEntityManagerFactory() line: 390    
        LocalContainerEntityManagerFactoryBean(AbstractEntityManagerFactoryBean).afterPropertiesSet() line: 377 
        LocalContainerEntityManagerFactoryBean.afterPropertiesSet() line: 341   
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeInitMethods(String, Object, RootBeanDefinition) line: 1767 
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1704    
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 581 
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 503   
        DefaultListableBeanFactory(AbstractBeanFactory).lambda$doGetBean$0(String, RootBeanDefinition, Object[]) line: 317  
        1800649922.getObject() line: not available  
        DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 222   
        DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 315    
        DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 199   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).getBean(String) line: 1089   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 859   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).refresh() line: 550  
        AnnotationConfigServletWebServerApplicationContext(ServletWebServerApplicationContext).refresh() line: 140  
        SpringApplication.refresh(ApplicationContext) line: 759 
        SpringApplication.refreshContext(ConfigurableApplicationContext) line: 395

        TableInformationImpl.indexes() line: 122    
        TableInformationImpl.getIndex(Identifier) line: 138 
        GroupedSchemaMigratorImpl(AbstractSchemaMigrator).applyUniqueKeys(Table, TableInformation, Dialect, Metadata, Formatter, ExecutionOptions, GenerationTarget...) line: 370   
        GroupedSchemaMigratorImpl.performTablesMigration(Metadata, DatabaseInformation, ExecutionOptions, Dialect, Formatter, Set<String>, boolean, boolean, Set<Identifier>, Namespace, GenerationTarget[]) line: 85   
        GroupedSchemaMigratorImpl(AbstractSchemaMigrator).performMigration(Metadata, DatabaseInformation, ExecutionOptions, Dialect, GenerationTarget...) line: 207 
        GroupedSchemaMigratorImpl(AbstractSchemaMigrator).doMigration(Metadata, ExecutionOptions, TargetDescriptor) line: 114   
        SchemaManagementToolCoordinator.performDatabaseAction(Action, Metadata, SchemaManagementTool, ServiceRegistry, ExecutionOptions) line: 183  
        SchemaManagementToolCoordinator.process(Metadata, ServiceRegistry, Map, DelayedDropRegistry) line: 72   
        SessionFactoryImpl.<init>(MetadataImplementor, SessionFactoryOptions) line: 312 
        SessionFactoryBuilderImpl.build() line: 462 
        EntityManagerFactoryBuilderImpl.build() line: 892   
        SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo, Map) line: 57    
        LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory() line: 365 
        LocalContainerEntityManagerFactoryBean(AbstractEntityManagerFactoryBean).buildNativeEntityManagerFactory() line: 390    
        LocalContainerEntityManagerFactoryBean(AbstractEntityManagerFactoryBean).afterPropertiesSet() line: 377 
        LocalContainerEntityManagerFactoryBean.afterPropertiesSet() line: 341   
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeInitMethods(String, Object, RootBeanDefinition) line: 1767 
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1704    
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 581 
        DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 503   
        DefaultListableBeanFactory(AbstractBeanFactory).lambda$doGetBean$0(String, RootBeanDefinition, Object[]) line: 317  
        473666452.getObject() line: not available   
        DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory<?>) line: 222   
        DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class<T>, Object[], boolean) line: 315    
        DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 199   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).getBean(String) line: 1089   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).finishBeanFactoryInitialization(ConfigurableListableBeanFactory) line: 859   
        AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).refresh() line: 550  
        AnnotationConfigServletWebServerApplicationContext(ServletWebServerApplicationContext).refresh() line: 140  
        SpringApplication.refresh(ApplicationContext) line: 759 
        SpringApplication.refreshContext(ConfigurableApplicationContext) line: 395  
        SpringApplication.run(String...) line: 327  

它正在从数据库中获取数据,不幸的是,没有在ResultSet或Statement上指定fetchSize。因此,当有数千个数据库对象时,此类操作将非常耗时。默认情况下,每次仅获取10条记录。 “ jdbc.fetch_size”设置不适用于这些代码逻辑。

        try {
        final ResultSet resultSet = statement.executeQuery( lookupSql );
        try {
            final List<SequenceInformation> sequenceInformationList = new ArrayList<SequenceInformation>();
            while ( resultSet.next() ) {
                sequenceInformationList.add(
                        new SequenceInformationImpl(
                                new QualifiedSequenceName(
                                        null,
                                        null,
                                        identifierHelper.toIdentifier(
                                                resultSet.getString( 1 )
                                        )
                                ),
                                -1
                        )
                );
            }
            return sequenceInformationList;
        }

是否有任何缓解此性能问题的建议?还是可以在将来的Hibernate版本中进行改进?

1 个答案:

答案 0 :(得分:0)

当前看来,唯一的解决方法是禁用ddl-auto。评论以下设置可以缓解此问题

#spring.jpa.hibernate.ddl-auto=update