Performance hibernate会话初始化在生产环境中非常缓慢,有许多实体定义

Performance hibernate会话初始化在生产环境中非常缓慢,有许多实体定义,performance,hibernate,spring-boot,session,initialization,Performance,Hibernate,Spring Boot,Session,Initialization,我有一个Spring Boot应用程序,其中有296个持久化对象,由@Entity使用Hibernate框架对persistence实现进行注释。在核心i7-6700(4x 3.4Ghz-4Ghz Turbo,SSD)上使用eclipse进行开发时,SessionFactory几乎在6秒钟内初始化 我的生产服务器是Xeon E5-2620v2(6x2,1GHz-2.6Ghz,硬盘(+SSD缓存))上的虚拟化windows服务器。我无法控制虚拟化所分配的资源 当我在这台服务器上运行我的应用程序时,

我有一个Spring Boot应用程序,其中有296个持久化对象,由@Entity使用Hibernate框架对persistence实现进行注释。在核心i7-6700(4x 3.4Ghz-4Ghz Turbo,SSD)上使用eclipse进行开发时,SessionFactory几乎在6秒钟内初始化

我的生产服务器是Xeon E5-2620v2(6x2,1GHz-2.6Ghz,硬盘(+SSD缓存))上的虚拟化windows服务器。我无法控制虚拟化所分配的资源

当我在这台服务器上运行我的应用程序时,实例化SessionFactory大约需要25秒

应用程序完全初始化时没有速度问题:所有Web服务/数据库查询的执行速度正常

我天真地认为,hibernate在实例化SessionFactory时会创建基本CRUD操作的SQL查询。 我尝试在所有@Entity类上添加@DynamicInsert和@DynamicUpdate,但没有给我带来更好的启动时间,SessionFactory实例化时间也是一样的

我使用以下spring/hibernate/others相关库版本:(来自我的pom.xml)

这就是我定义hibernate SessionFactory的方式(我知道我可以使用标准的JPA会话工厂,但这个应用程序就是这样制作的,我不想改变它,而且我简化了类内容以提高可读性):

这种速度差正常吗? 我忘了hibernate配置中的一些东西了吗?
欢迎提供任何帮助。

您的虚拟服务器有多少资源?@Simon Martinelli我的虚拟服务器有4个vCPU(2.10 Ghz),32 GB的RAM(但我将我的应用程序实例限制为-Xms256m-Xmx512m-性能相同,没有RAM限制)。目前,我对虚拟服务器资源还不太了解。你认为这可能是问题的根源吗,那么我应该调查一下?你在本地运行时也限制XMX吗?不,但我刚刚尝试过,SessionFactory实例化时间是相同的(~6秒),你有一个HDD而不是SDD,对吗?还有病毒扫描器吗?你的虚拟服务器有多少资源?@Simon Martinelli我的虚拟服务器有4个vCPU(2.10 Ghz),32 GB的RAM(但我用-Xms256m-Xmx512m限制我的应用程序实例-没有RAM限制,性能相同)。目前,我对虚拟服务器资源还不太了解。你认为这可能是问题的根源吗,那么我应该调查一下?你在本地运行时也限制XMX吗?不,但我刚刚尝试过,SessionFactory实例化时间是相同的(~6秒),你有一个HDD而不是SDD,对吗?有病毒扫描器吗?
<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>
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
@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 ...
}