使用JPA进行Hibernate,连接时间非常慢

时间:2015-04-16 09:42:12

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

我有一个项目,我想使用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,此延迟仅约为200毫秒。

在此期间,进程内存不会更改,cpu使用率为0%,并且根据sysinternals Process Monitor有0次交互。

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

使用的工具: 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">

3 个答案:

答案 0 :(得分:2)

找到解决方案,现在我是一个快乐的人!

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文件(如果不指定实际文件,则无法使用reve)。

答案 1 :(得分:1)

此问题可能与一个属性有关,该属性调节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>

答案 2 :(得分:0)

或者,您可以直接从JAR文件中加载dtd:

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