【问题标题】:Hibernate with JPA, connection time very slow使用 JPA 休眠,连接时间很慢
【发布时间】:2015-04-16 09:42:11
【问题描述】:

我有一个项目,我想使用 Hibernate 进行数据库访问。在应用程序中,使用了 JPA api。

persistence.xml文件是这样的

<persistence 
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
    <persistence-unit name="hibernate.test"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="hibernate.ejb.cfgfile" value="/hibernate/hibernate.cfg.xml"/>
        </properties>
    </persistence-unit>
</persistence>

hibernate.cfg.xml文件如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory>
  <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:oracle:thin:@//server:1521/DBNAME</property>
  <property name="hibernate.connection.username">username</property>
  <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
  <!-- <property name="hibernate.hbm2ddl.auto">verify</property>  -->
  <property name="hibernate.default_catalog">SYS_SOMETHING</property>
  <property name="hibernate.default_schema">SYS_SOMETHING</property>
 </session-factory>
</hibernate-configuration>

问题在于这个设置,entityManagerFactory = Persistence.createEntityManagerFactory("hibernate.test");

通话大约需要 25 秒才能完成。

如果我将配置直接移动到persistence.xml 文件中,连接将在1 秒内完成。 Oracle 和 MySQL 数据库都会出现此错误。

我可以在日志文件中看到延迟,这段时间没有发生任何其他事情

525 [pool-2-thread-1] INFO org.hibernate.cfg.Environment  - HHH000021: Bytecode provider name : javassist
21668 [pool-2-thread-1] DEBUG org.hibernate.service.internal.JaxbProcessor  - cfg.xml document did not define namespaces; wrapping in custom event reader to introduce namespace information

完整日志:http://pastebin.com/4NjPpFPe

如果不使用cfg.xml,这个延迟只有200ms左右。

在此期间,进程内存没有变化,cpu 使用率为 0%,根据 sysinternals Process Monitor 有 0 次交互。

我想保留此设置,因为 hibernate.cfg.xml 也用于逆向工程和休眠工具。

使用的工具: java8 休眠-4.3.8 ojdbc7 jpa-2.1

提前感谢您的任何建议。

更新:

找到了解决办法,现在我是一个快乐的人!

hibernate 框架(或 xml 解析器,我不确定)会等待 http 请求。

要解决问题,请替换

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<!DOCTYPE hibernate-configuration SYSTEM "-//Hibernate/Hibernate Configuration DTD 3.0//EN">

【问题讨论】:

  • 服务器启动时延迟是不是只有一次?
  • 每次启动应用,创建EntityManagerFactory时,EntityManagers和查询等都很快。
  • 当您运行项目并启动服务器时。需要多少时间?我想说的是,启动像 Jboss 或 tomcat 这样的服务器或您运行的任何服务器是正常的,需要 25 秒!
  • FWIW "hibernate.cfg.xml" 与JPA无关,应该合并到persistence.xml中
  • @kucing_terbang 非常感谢您抽出宝贵时间。我只是有时间去做。这个过程挂在一个http请求中。更改 xml DOCTYPE 将解决问题。我会用解决方案更新问题。

标签: java hibernate jpa persistence.xml hibernate.cfg.xml


【解决方案1】:

找到了解决办法,现在我是一个快乐的人!

hibernate 框架(或 xml 解析器,我不确定)会等待 http 请求。

要解决问题,请替换

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<!DOCTYPE hibernate-configuration SYSTEM "hibernate-configuration-3.0.dtd">

编辑:替换了“with”行,这将在发布模式和逆向工程中使用正确的 dtd 文件(如果不指定实际文件就无法使用 reveng)。

【讨论】:

  • 很高兴,它在你的情况下成功了。不过,这只是一种解决方法,因为您正在跳过 XML 模式的内部验证。恕我直言,这不是一个真正的解决方案,也许您应该向 Hibernate 问题跟踪器提交错误报告?
  • 请考虑不要将此答案标记为解决方案,因为它是“仅”的解决方法
  • @MWiesner 更新了我的答案,它应该验证它。 Eclipse 也可以识别它。似乎休眠尝试在线访问 dtd,但它位于代理服务器后面。如果我跳过它,将使用包中的 dtd。
  • 好的,看起来很合理,但我无法确认,因为我没有彻底测试。
【解决方案2】:

此问题可能与调节 Hibernate 内部行为以在首次尝试创建连接时处理 JDBC 元数据的属性有关。

尝试添加此属性

"hibernate.temp.use_jdbc_metadata_defaults"

到你的 hibernate.cfg.xml。这帮助我在 PostgreSQL 环境中解决了类似的问题,使“蹩脚”的初创公司恢复了“生机”。默认情况下(即未明确定义)此属性设置为true,这会导致通过 JDBC 完全加载数据库的所有元数据(在某些情况下这显然会很慢......)。

hibernate.cfg.xml 文件应该按如下方式使用

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory>
  <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
  <property name="hibernate.connection.password">password</property>
  <property name="hibernate.connection.url">jdbc:oracle:thin:@//server:1521/DBNAME</property>
  <property name="hibernate.connection.username">username</property>
  <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
  <!-- <property name="hibernate.hbm2ddl.auto">verify</property>  -->
  <property name="hibernate.default_catalog">SYS_SOMETHING</property>
  <property name="hibernate.default_schema">SYS_SOMETHING</property>
  <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
 </session-factory>
</hibernate-configuration>

【讨论】:

  • 遗憾的是,这对速度没有(明显的)影响。
  • @BiróKrisztián 我同意。有什么解决办法吗?
【解决方案3】:

您也可以直接从 JAR 文件加载 dtd:

<!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
        "classpath://org/hibernate/hibernate-mapping-3.0.dtd">

【讨论】:

    猜你喜欢
    • 2014-08-08
    • 1970-01-01
    • 2017-08-03
    • 2013-11-24
    • 1970-01-01
    • 2012-04-21
    • 2013-04-18
    • 2012-03-31
    • 1970-01-01
    相关资源
    最近更新 更多