Hibernate ralentit pour acquérir une connexion Postgres

J’ai beaucoup de mal à résoudre ce problème. Chaque fois que j’essaie d’établir une connexion avec postgres, cela prend une minute entière. Une fois la connexion établie, tout va bien. J’ai essayé de désactiver tous les mappages et de ne pas en charger, mais la connexion prend beaucoup de temps. J’ai aussi essayé de désactiver la validation, pas de différence. Lorsque j’utilise une simple connexion JDBC, c’est instantané. Hibernate fait quelque chose qui prend beaucoup de temps et je n’arrive pas à le réduire. Toute consortingbution est grandement appréciée!

Postgres Driver:

postgresql-9.1-901.jdbc4.jar 

Paramètres de configuration:

    org.hibernate.dialect.PostgreSQLDialect org.postgresql.Driver jdbc:postgresql://xxxx.com:5432/xxxxx xxxxxxx xxxxxxx   

Paramètres supplémentaires dans le code:

  config.setProperty("hibernate.hbm2ddl.auto", hbm2ddlMode); //config.setProperty("hibernate.cache.use_query_cache", "true"); config.setProperty("hibernate.cache.use_second_level_cache", "true"); //config.setProperty("hibernate.cache.region.factory_class", "net.sf.ehcache.hibernate.EhCacheRegionFactory"); config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider"); //config.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider"); config.setProperty("hibernate.jdbc.fetch_size", "100"); config.setProperty("hibernate.jdbc.batch_size", "30"); config.setProperty("hibernate.jdbc.use_scrollable_resultset", "true"); config.setProperty("hibernate.connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider"); config.setProperty("hibernate.c3p0.acquire_increment", "1"); config.setProperty("hibernate.c3p0.idle_test_period", "0"); config.setProperty("hibernate.c3p0.min_size", "1"); config.setProperty("hibernate.c3p0.max_size", "2"); config.setProperty("hibernate.c3p0.timeout", "0"); config.setProperty("javax.persistence.validation.mode", "none"); 

Voici le segment de code où le délai se produit:

 private SessionFactory buildSessionFactory() throws Exception { ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry(); //Building session takes a whole minute without mappings!!! sessionFactory = config.buildSessionFactory(serviceRegistry); validateConnection(); return sessionFactory; } 

Voici les résultats du journal:

 [main] 2012-04-09 10:40:32,823 110391 INFO C3P0ConnectionProvider - HHH000046: Connection properties: {user=hgaidb_test, password=****} [main] 2012-04-09 10:40:32,823 110391 INFO C3P0ConnectionProvider - HHH000006: Autocommit mode: false [main] 2012-04-09 10:40:34,100 111668 DEBUG JdbcServicesImpl - Database -> name : PostgreSQL version : 8.3.3 major : 8 minor : 3 [main] 2012-04-09 10:40:34,101 111669 DEBUG JdbcServicesImpl - Driver -> name : PostgreSQL Native Driver version : PostgreSQL 9.1 JDBC4 (build 901) major : 9 minor : 1 ******************************************************************************* // 1 MINUTE DELAY ******************************************************************************* [main] 2012-04-09 10:40:34,102 111670 DEBUG JdbcServicesImpl - JDBC version : 4. 0 [main] 2012-04-09 10:41:21,632 159200 INFO Dialect - HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect ******************************************************************************* [main] 2012-04-09 10:41:21,669 159237 INFO LobCreatorBuilder - HHH000424: Disab ling contextual LOB creation as createClob() method threw error : java.lang.refl ect.InvocationTargetException [main] 2012-04-09 10:41:21,814 159382 DEBUG SettingsFactory - Automatic flush du ring beforeCompletion(): disabled [main] 2012-04-09 10:41:21,814 159382 DEBUG SettingsFactory - Automatic session close at end of transaction: disabled [main] 2012-04-09 10:41:21,815 159383 DEBUG SettingsFactory - JDBC batch size: 3 0 [main] 2012-04-09 10:41:21,816 159384 DEBUG SettingsFactory - JDBC batch updates for versioned data: disabled [main] 2012-04-09 10:41:21,816 159384 DEBUG SettingsFactory - Scrollable result sets: enabled [main] 2012-04-09 10:41:21,817 159385 DEBUG SettingsFactory - Wrap result sets: disabled [main] 2012-04-09 10:41:21,818 159386 DEBUG SettingsFactory - JDBC3 getGenerated Keys(): enabled [main] 2012-04-09 10:41:21,818 159386 DEBUG SettingsFactory - JDBC result set fe tch size: 100 [main] 2012-04-09 10:41:21,819 159387 DEBUG SettingsFactory - Connection release mode: auto [main] 2012-04-09 10:41:21,819 159387 INFO TransactionFactoryInitiator - HHH000 399: Using default transaction strategy (direct JDBC transactions) [main] 2012-04-09 10:41:21,844 159412 DEBUG SettingsFactory - Default batch fetc h size: 1 [main] 2012-04-09 10:41:21,844 159412 DEBUG SettingsFactory - Generate SQL with comments: disabled [main] 2012-04-09 10:41:21,845 159413 DEBUG SettingsFactory - Order SQL updates by primary key: disabled [main] 2012-04-09 10:41:21,846 159414 DEBUG SettingsFactory - Order SQL inserts for batching: disabled [main] 2012-04-09 10:41:21,846 159414 DEBUG SettingsFactory - Query translator: org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory [main] 2012-04-09 10:41:21,867 159435 INFO ASTQueryTranslatorFactory - HHH00039 7: Using ASTQueryTranslatorFactory [main] 2012-04-09 10:41:21,867 159435 DEBUG SettingsFactory - Query language sub stitutions: {} [main] 2012-04-09 10:41:21,867 159435 DEBUG SettingsFactory - JPA-QL ssortingct comp liance: disabled [main] 2012-04-09 10:41:21,868 159436 DEBUG SettingsFactory - Second-level cache : enabled [main] 2012-04-09 10:41:21,868 159436 DEBUG SettingsFactory - Query cache: disab led [main] 2012-04-09 10:41:21,869 159437 DEBUG SettingsFactory - Cache region facto ry : org.hibernate.cache.internal.NoCachingRegionFactory [main] 2012-04-09 10:41:21,872 159440 DEBUG SettingsFactory - org.hibernate.cach e.internal.NoCachingRegionFactory did not provide constructor accepting java.uti l.Properties; attempting no-arg constructor. [main] 2012-04-09 10:41:21,873 159441 DEBUG SettingsFactory - Optimize cache for minimal puts: disabled [main] 2012-04-09 10:41:21,873 159441 DEBUG SettingsFactory - Structured second- level cache ensortinges: disabled [main] 2012-04-09 10:41:21,873 159441 DEBUG SettingsFactory - Statistics: disabl ed [main] 2012-04-09 10:41:21,874 159442 DEBUG SettingsFactory - Deleted entity syn thetic identifier rollback: disabled [main] 2012-04-09 10:41:21,874 159442 DEBUG SettingsFactory - Default entity-mod e: pojo [main] 2012-04-09 10:41:21,875 159443 DEBUG SettingsFactory - Named query checki ng : enabled [main] 2012-04-09 10:41:21,875 159443 DEBUG SettingsFactory - Check Nullability in Core (should be disabled when Bean Validation is on): enabled [main] 2012-04-09 10:41:21,876 159444 DEBUG SettingsFactory - multi-tenancy stra tegy : NONE 

J’ai fait un peu plus de recherche à ce sujet, en parcourant le débogueur. Je n’ai pas toutes les sources dans mon classpath, mais je peux toujours voir les variables. Pendant cette minute d’attente, Hibernate interroge la table pg_catalog.pg_type:

 [SELECT typname FROM pg_catalog.pg_type WHERE oid = , ] 

Voici une copie d’écran:

DebugWindow

Je l’ai corrigé =) Il fallait vraiment que je cherche à trouver la réponse à celle-ci. Fondamentalement, il s’agit de charger les métadonnées et le pilote JDBC. Il charge ALL META DATA, y compris les commentaires à côté des colonnes sql et d’autres constructions diverses, qui ne sont pas nécessaires pour l’opération. Je ne sais pas pourquoi cela est activé par défaut, mais vous devriez certainement désactiver cette fonctionnalité, sauf si vous en avez explicitement besoin:

 config.setProperty("hibernate.temp.use_jdbc_metadata_defaults","false"); 

Connexion instantanée maintenant!

La seule information que je pourrais trouver à ce sujet est dans le code:

 107 // 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value. 108 // The need for it is intended to be alleviated with future development, thus it is 109 // not defined as an Environment constant... 110 // 111 // it is used to control whether we should consult the JDBC metadata to determine 112 // certain Settings default values; it is useful to *not* do this when the database 113 // may not be available (mainly in tools usage). 114 boolean useJdbcMetadata = ConfigurationHelper.getBoolean( "hibernate.temp.use_jdbc_metadata_defaults", configValues, true ); 

http://grepcode.com/file/repo1.maven.org/maven2/org.hibernate/hibernate-core/4.1.1.Final/org/hibernate/engine/jdbc/internal/JdbcServicesImpl.java#JdbcServicesImpl

Je devais également activer hibernate.jdbc.use_get_generated_keys sinon la stratégie de génération d’identité émettait une exception. Avant, il était activé automatiquement en fonction des métadonnées reçues de DB. Donc, toute ma solution consistait à append les deux lignes suivantes à persistence.xml:

   

Un serveur postgresql peut contenir plusieurs bases de données. Malheureusement, vous ne pouvez pas masquer les métadonnées d’une autre firebase database , c’est pourquoi la lecture des métadonnées prend beaucoup de temps au pilote jdbc!

Séparez ces bases de données en différents serveurs postgres et les performances de lecture des métadonnées seront augmentées!

Lisez comment séparer sur centos .

Cela ressemble vaguement à un problème que nous avons vu dans Ruby on Rails. Vous pourriez chercher une cause similaire à celle que j’ai décrite ici:

http://archives.postgresql.org/pgsql-performance/2009-11/msg00128.php

En bref, ce problème est dû à l’enregistrement explicite du pilote JDBC à partir de plusieurs contextes ClassLoader.