postgresql Hibernate 启动很慢

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14445838/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 00:45:00  来源:igfitidea点击:

Hibernate startup very slow

javahibernatepostgresqljdbcpostgresql-9.1

提问by bentrm

For some reason, the startup of my hibernate application is unbarrably slow. (up to 2 min) I have been thinking that the c3p0 configuration is plain wrong (related question) but studying the logs shows, that there is no activity just after the connection to the server is established. Also, using the built-in polling capabilities of Hibernate shows the same result.

出于某种原因,我的休眠应用程序的启动速度非常慢。(最多 2 分钟)我一直认为 c3p0 配置完全错误(相关问题),但研究日志显示,在与服务器的连接建立后没有任何活动。此外,使用 Hibernate 的内置轮询功能显示相同的结果。

Here is a snippet from the logs:

这是日志中的一个片段:

20:06:51,248 DEBUG BasicResourcePool:422 - decremented pending_acquires: 0
20:06:51,248 DEBUG BasicResourcePool:1644 - trace com.mchange.v2.resourcepool.BasicResourcePool@1acaf0ed [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@5f873eb2)
20:06:51,248 DEBUG BasicResourcePool:1644 - trace com.mchange.v2.resourcepool.BasicResourcePool@1acaf0ed [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@5f873eb2)
20:06:51,273 DEBUG JdbcServicesImpl:121 - Database ->
       name : PostgreSQL
    version : 9.1.6
      major : 9
      minor : 1
20:06:51,274 DEBUG JdbcServicesImpl:127 - Driver ->
       name : PostgreSQL Native Driver
    version : PostgreSQL 9.2 JDBC4 (build 1002)
      major : 9
      minor : 2
20:06:51,274 DEBUG JdbcServicesImpl:133 - JDBC version : 4.0 ##### HANGS FOR 2 MINUTES  ON THIS LINE #####
20:08:14,727  INFO Dialect:123 - HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
20:08:14,736  INFO LobCreatorBuilder:120 - HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException
20:08:14,736 DEBUG GooGooStatementCache:297 - checkinAll(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0
20:08:14,736 DEBUG GooGooStatementCache:297 - checkinAll(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0
20:08:14,883 DEBUG BasicResourcePool:1644 - trace com.mchange.v2.resourcepool.BasicResourcePool@1acaf0ed [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@5f873eb2)
20:08:14,883 DEBUG BasicResourcePool:1644 - trace com.mchange.v2.resourcepool.BasicResourcePool@1acaf0ed [managed: 3, unused: 2, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@5f873eb2)
20:08:14,883 DEBUG GooGooStatementCache:297 - checkinAll(): com.mchange.v2.c3p0.stmt.GlobalMaxOnlyStatementCache stats -- total size: 0; checked out: 0; num connections: 0; num keys: 0

(Please mind the #comment#.)

(请注意#comment#。)

I also tried an older Postgres JDBC Driver with no luck whatsoever.

我还尝试了一个旧的 Postgres JDBC 驱动程序,但没有任何运气。

Connecting to a local Database works just fine. Connection is established immediately and I can query the database. This remote db is a Heroku dev instance. I tried it with another remote as well. Same outcome.

连接到本地数据库工作正常。连接立即建立,我可以查询数据库。这个远程数据库是一个 Heroku 开发实例。我也用另一个遥控器试过。结果一样。

I'm out of ideas what I can check now to get rid of this annoyance. Any help would be much appreciated.

我不知道我现在可以检查什么来摆脱这种烦恼。任何帮助将非常感激。

Maybe my hibernate.cfg.xml is helpful:

也许我的 hibernate.cfg.xml 有帮助:

http://www.hibernate.org/dtd/hibernate-

http://www.hibernate.org/dtd/hibernate-

configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url"/>
        <property name="connection.default_schema"/>
        <property name="connection.username"/>
        <property name="connection.password"/> 

        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
            <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
        <property name="current_session_context_class">thread</property>            
        <property name="hibernate.c3p0.acquire_increment">3</property>
        <property name="hibernate.c3p0.min_size">3</property>
        <property name="hibernate.c3p0.max_size">10</property>
        <property name="hibernate.c3p0.timeout">300</property>
        <property name="hibernate.c3p0.max_statements">50</property>
        <property name="hibernate.c3p0.idle_test_period">3000</property>
        <property name="hibernate.c3p0.acquireRetryDelay">500</property>

        <property name="show_sql">true</property>
        <property name="format_sql">false</property>

        <property name="hbm2ddl.auto">validate</property>

        <mapping class="core.entities.Exam" />
        <mapping class="core.entities.Examination" />
        ...
    </session-factory>
</hibernate-configuration>

EDIT: I tried to find the reason for the delay via logs and profiling but have been widely unsuccessful with it. (I'm not that advanced in this area though.) In the end I did go with try and fail and changed my db for a remote MySQL instance to check if any difference occurs. Turns out, that the connection is established nearly immediately.

编辑:我试图通过日志和分析找到延迟的原因,但一直没有成功。(不过,我在这方面并不是那么先进。)最后,我确实尝试并失败了,并更改了远程 MySQL 实例的数据库以检查是否发生任何差异。事实证明,连接几乎立即建立。

回答by Darryl Miles

See Hibernate Slow to Acquire Postgres Connection

参见Hibernate 缓慢获取 Postgres 连接

hibernate.temp.use_jdbc_metadata_defaults=false

hibernate.temp.use_jdbc_metadata_defaults=false

To avoid meta-data reload during SessionFactory creation.

避免在 SessionFactory 创建期间重新加载元数据。

回答by Ricardo Spinoza

For Postgres, add in application config:

对于 Postgres,添加应用程序配置:

spring.jpa.database-platform = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false

First line is necessary if not determine Dialect

如果没有确定方言,第一行是必要的

Results

结果

Before:

前:

09:10:19.637 [main] INFO  o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
09:14:17.159 [main] INFO  org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL9Dialect

~4 minutes

~4 分钟

After:

后:

09:40:10.930 [main] INFO  o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
09:40:11.043 [main] INFO  org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect

~1 minute

~1 分钟

回答by kidfruit

Startup slow may be caused by this config:

此配置可能导致启动缓慢:

<property name="hbm2ddl.auto">update</property>

This config means when hibernate start, check if the entity matching with ddl, and do action such as 'create','update'. This will cost too much time.

这个配置意味着在hibernate开始时,检查实体是否与ddl匹配,并做'create','update'等动作。这将花费太多时间。

So the solution is comment this config. Then hibernate will start without validate.

所以解决方案是评论这个配置。然后休眠将在没有验证的情况下启动。

回答by Mirko Adari

If it is abnormally slow then you probably have a lock in your application, or some resource blocks. In any case download VisualVM (JDK includes jconsole, dumbed down version of it) and check what your threads are doing, where they are stuck (threaddump) and if that doesn't give any quick answers, turn on the profiler.

如果它异常缓慢,那么您的应用程序可能被锁定,或者某些资源块。在任何情况下都下载 VisualVM(JDK 包括 jconsole,它的简化版本)并检查您的线程正在做什么,它们被卡在何处(线程转储),如果这没有给出任何快速答案,请打开分析器。

回答by Rob

What container are you using? c3p0 should be installed in the container, e.g Tomcat. If you are running unit tests, for chrissakes, don't use a connection pool. If you put it into tomcat, you do that with a Resource tag and then connect to it using JNDI. Best way to do it.

你用的是什么容器?c3p0 应该安装在容器中,例如 Tomcat。如果您正在运行单元测试,请不要使用连接池。如果将其放入 tomcat,则使用 Resource 标记执行此操作,然后使用 JNDI 连接到它。最好的方法来做到这一点。