Hibernate Slow для получения соединения Postgres
Мне очень сложно отладить эту проблему. Всякий раз, когда я пытаюсь установить связь с postgres, это занимает целую минуту. После установления соединения все в порядке. Я попытался отключить все сопоставления, а не загружать их, но все же соединение занимает много времени. Я также попытался отключить проверку, без разницы. Когда я использую простое JDBC-соединение, оно мгновенно. Hibernate делает то, что занимает много времени, и я не могу сузить его. Любой вход очень приветствуется!
Драйвер Postgres:
postgresql-9.1-901.jdbc4.jar
Настройки конфигурации:
<hibernate-configuration>
<session-factory>
<!-- properties -->
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://xxxx.com:5432/xxxxx</property>
<property name="connection.username">xxxxxxx</property>
<property name="connection.password">xxxxxxx</property>
</session-factory>
</hibernate-configuration>
Дополнительные настройки в коде:
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");
Здесь сегмент кода, в котором происходит задержка:
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;
}
Здесь результаты журнала:
[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 strict 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 entries: 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
Я сделал немного больше исследований по этому вопросу, пройдя через отладчик. У меня нет всего источника в моем пути к классам, но я все еще вижу переменные. Подумав, что в одну минуту подождите, Hibernate запрашивает таблицу pg_catalog.pg_type:
[SELECT typname FROM pg_catalog.pg_type WHERE oid = , ]
Вот скриншот:
![DebugWindow]()
Ответы
Ответ 1
Я исправил его =) Мне действительно пришлось корень, чтобы найти ответ для этого. В основном, это сводится к загрузке метаданных и драйвера JDBC. Он загружает ВСЕ META DATA, включая комментарии к столбцам sql и другие различные конструкции, которые не нужны для работы. Я не знаю, почему это по умолчанию, но вы обязательно должны отключить эту функцию, если вы явно не нуждаетесь в ней:
config.setProperty("hibernate.temp.use_jdbc_metadata_defaults","false");
Мгновенное соединение сейчас!
Единственная информация, которую я могу найти, это код:
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
Ответ 2
Мне также нужно было включить hibernate.jdbc.use_get_generated_keys, иначе стратегия генерации удостоверений выбрала исключение. До того, как он был включен автоматически на основе метаданных, полученных от БД. Поэтому все мое решение заключалось в том, чтобы добавить следующие две строки в persistence.xml:
<property name="hibernate.jdbc.use_get_generated_keys" value="true" />
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
Ответ 3
Один сервер postgresql может содержать несколько баз данных. К сожалению, вы не можете скрыть метаданные других баз данных к одному соединению, поэтому чтение метаданных занимает много времени с помощью jdbc-драйвера!
Разделяйте эти базы данных на разных серверах postgres, а производительность чтения метаданных будет увеличена!
Прочитайте как разделить на centos.
Ответ 4
У меня были проблемы с прокручиваемым набором результатов, поэтому мне пришлось добавить третий параметр, см. Ниже:
<property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
<property name="hibernate.jdbc.use_get_generated_keys">true</property>
<property name="hibernate.jdbc.use_scrollable_resultset">true</property>
Ответ 5
Это звучит неопределенно, как проблема, которую мы видели в Ruby on Rails. Вы можете найти аналогичную причину тому, что я описал здесь:
http://archives.postgresql.org/pgsql-performance/2009-11/msg00128.php
Короче говоря, эта проблема была вызвана явной регистрацией драйвера JDBC из нескольких контекстов ClassLoader.
Ответ 6
Спустя почти 7 лет, и это все еще проблема...
Выключение клавиши "temp" помогает, но неудобно включать свойства по одному, которые будут автоматически настраиваться (см. Другие ответы).
В случае с Oracle и Teradata я не заметил такого замедления, поэтому я углубился и нашел, где самая медленная часть: https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/орг /PostgreSQL/JDBC/PgDatabaseMetaData.java # L2237
Этот resultSet имеет в моем случае 372 строки (типы). Затем для каждого драйвера запускается несколько вызовов из https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java#L204, что приводит к тоннам Операторы SQL против БД.
Не знаю, как ускорить это прямо сейчас, к счастью, это понадобилось один раз, а затем кешировалось.