инициализация сеанса гибернации очень медленная в работе с определением многих объектов - PullRequest
1 голос
/ 26 сентября 2019

У меня есть приложение Spring Boot с 296 постоянными объектами, аннотированными @ Entity с использованием инфраструктуры Hibernate для реализации сохраняемости.При разработке с использованием Eclipse на Core i7-6700 (4x 3,4 ГГц - 4 ГГц Turbo, SSD) SessionFactory инициализируется почти за 6 секунд.

Мой рабочий сервер представляет собой виртуальный сервер Windows на Xeon E5-2620v2 (6x 2,1 ГГц - 2,6 ГГц, HDD (+ кэш SSD)).У меня нет контроля над распределением ресурсов при виртуализации.

Когда я запускаю свое приложение на этом сервере, создание экземпляра SessionFactory занимает около 25 секунд.

Нет проблем со скоростью, когда приложение полностью инициализировано: скорость выполнения всех запросов веб-сервисов / баз данных нормальная.

Наивно я думаю, что hibernate создает SQL-запросы базовых операций CRUD, когда создается экземпляр SessionFactory.Я попытался добавить @ DynamicInsert и @ DynamicUpdate на все классы @ Entity , но это не принесло мне лучшего времени запуска и времени создания SessionFactory.

Я использую следующие подходящие версии библиотек spring / hibernate / others: (из моего pom.xml)

<hibernate.version>5.4.5.Final</hibernate.version>
<spring.version>5.1.9.RELEASE</spring.version>
<springSecurity.version>5.1.6.RELEASE</springSecurity.version>
<springBoot.version>2.1.8.RELEASE</springBoot.version>
<mssql-jdbc.version>7.4.1.jre11</mssql-jdbc.version>
<apache-commons-dbcp2.version>2.5.0</apache-commons-dbcp2.version>
<eh-cache.version>2.10.6</eh-cache.version>
<javaassist.version>3.25.0-GA</javaassist.version>

Это моя конфигурация hessionnate SessionFactory (часть файла application.mssql.properties):

hibernate.dialect = org.hibernate.dialect.SQLServer2012Dialect

# useless cause I use GenerationType.IDENTITY 
# for primary key (id) of all entities
hibernate.jdbc.batch_size = 20 

hibernate.cache.use_query_cache = false
hibernate.cache.use_second_level_cache = true
hibernate.cache.provider_class = org.hibernate.cache.EhCacheProvider
hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.connection.driver_class = com.microsoft.sqlserver.jdbc.SQLServerDriver
hibernate.enable_lazy_load_no_trans = true
hibernate.cache.use_reference_entries = true
hibernate.connection.url =  jdbc:sqlserver://localhost:1433;databaseName=master;user=usr;password=pwd;
hibernate.connection.username = usr
hibernate.connection.password = pwd

# Multitenancy configuration
hibernate.multiTenancy = SCHEMA
hibernate.multi_tenant_connection_provider = MultiTenantConnectionProvider
hibernate.tenant_identifier_resolver = CurrentTenantIdentifierResolver

Именно так я определяю свою гибернацию SessionFactory (я знаю, что могу использовать стандартную фабрику сессий JPA, но это приложение было сделано таким образом, и я не хочу это менять, более того, яупростили содержание класса для большей читаемости):

@SpringBootApplication()
@EnableAutoConfiguration(
    excludeName = { 
        "org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration"
    }
)
@ComponentScan(
    basePackages = {
        // my packages list
    }
)
@Configuration
@PropertySource({ "classpath:application.mssql.properties" })
@EnableCaching
@EnableTransactionManagement
public class ApplicationConfiguration {

    @Autowired
    private Environment env;

    /**
     * @return SQL-Server pooled connection using apache dbcp2
     */
    @Primary
    @Bean
    public DataSource dataSource() {    

        BasicDataSource ds = new BasicDataSource();

        ds.setUrl(this.env.get("hibernate.connection.url"));
        ds.setUsername(this.env.get("hibernate.connection.username"));
        ds.setPassword(this.env.get("hibernate.connection.password"));
        ds.setDriverClassName(this.env.get("hibernate.connection.driver_class"));
        ds.setMaxIdle(10);
        ds.setMaxOpenPreparedStatements(100);

        return ds;

    }


    /**
     * @return main sessionFactory (the mostly used sessionFactory in app)
     */
    @Primary
    @Autowired
    @Bean
    public LocalSessionFactoryBean sessionFactory(@Qualifier("dataSource") DataSource dataSource,
                                                  MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
                                                  CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl) {

        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();

        sessionFactory.setPackagesToScan("my.root.pojo.package");

        // get hibernate properties from this.env (application.mssql.properties file)
        Properties hibernateProperties = getHibernateProperties();

        hibernateProperties.put(AvailableSettings.MULTI_TENANT, "SCHEMA");
        hibernateProperties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProviderImpl);
        hibernateProperties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolverImpl);

        sessionFactory.setHibernateProperties(hibernateProperties);
        sessionFactory.setDataSource(dataSource);

        return sessionFactory;


        // FROM THIS POINT --->
    }

    /**
     * @return transactionManager for main sessionFactory
     */ 
    @Bean
    @Autowired
    @Primary
    public HibernateTransactionManager transactionManager(@Qualifier("sessionFactory") SessionFactory sessionFactory) {

        // ----> TO THIS POINT took 6 sec in development, 25 sec in production

        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setNestedTransactionAllowed(true);
        txManager.setSessionFactory(sessionFactory);
        return txManager;
    }


    // some other stuff: 
    //   - sessionFactory on another databases,
    //   - getHibernateProperties() implementation,
    //   - initServer() method annotated by @Bean(initMethod = "init")
    //   - etc ...
}

Нормально ли иметь эту разницу в скорости?Я что-то забыл в спящем состоянии?Любая помощь будет приветствоваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...