У меня есть приложение 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 ...
}
Нормально ли иметь эту разницу в скорости?Я что-то забыл в спящем состоянии?Любая помощь будет приветствоваться.