java - 从 Hibernate 3 迁移到 4 会减慢启动速度

标签 java performance hibernate orm configuration

我们正在尝试将我们的项目从 hibernate 3 迁移到 hibernate 4。一切正常,但问题是启动。

我们不使用 JPA,我们使用带有 xml 文件和映射文件的直接 hibernate 。

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        <property name="hibernate.connection.driver_class">com.informix.jdbc.IfxDriver</property>
        <property name="hibernate.connection.url">jdbc:informix-sqli://xxx:xxx/xxx:INFORMIXSERVER=xxx</property>
        <property name="hibernate.connection.username">xxx</property>
        <property name="hibernate.connection.password">xxx</property>
        <property name="hibernate.dialect">org.hibernate.dialect.InformixDialect</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.show_sql">false</property>        


        <property name="generated.mappingFile">dev.xml</property>
   </session-factory>
</hibernate-configuration>

属性 generated.mappingFile 是一个自己的属性。启动时将加载文件 (dev.xml)。该文件如下所示:

        <mapping resource="de/cargosoft/edi/cargoservice/entities/aart/Aart_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/abteilung/Abteilung_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/adr/Adr_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/adraesort/Adraesort_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/adrakte/Adrakte_DEV.hbm.xml" />
        ...
        <mapping resource="de/cargosoft/edi/cargoservice/entities/zollanmtxt/Zollanmtxt_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/sstbasis/Sstbasis_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/sststruktur/Sststruktur_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/ssthandler/Ssthandler_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/sstproperty/Sstproperty_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/sstprophandler/Sstprophandler_DEV.hbm.xml" />
        <mapping resource="de/cargosoft/edi/cargoservice/entities/sstneustart/Sstneustart_DEV.hbm.xml" />

我们减少了这篇文章中的映射数量。目前我们确实有超过 500 个映射

使用 hibernate 3 加载所有映射需要 2 秒。使用 hibernate 4 需要 2 多分钟

这是来自 hibernate 3.2.GA 的日志文件:

     07:36:21,293 INFO  [HibernateManager              ] | Verwende Mapping-Collection Datei : /com/cargosoft/csedi/data/mappings_dev.xml
     07:36:21,347 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/aart/Aart_DEV.hbm.xml
     07:36:21,443 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/abteilung/Abteilung_DEV.hbm.xml
     07:36:21,458 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/adr/Adr_DEV.hbm.xml
     07:36:21,495 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/adraesort/Adraesort_DEV.hbm.xml
     07:36:21,523 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/adrakte/Adrakte_DEV.hbm.xml
     ...
     07:36:23,475 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/zollanmtxt/Zollanmtxt_DEV.hbm.xml
     07:36:23,477 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/sstbasis/Sstbasis_DEV.hbm.xml
     07:36:23,479 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/sststruktur/Sststruktur_DEV.hbm.xml
     07:36:23,481 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/ssthandler/Ssthandler_DEV.hbm.xml
     07:36:23,482 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/sstproperty/Sstproperty_DEV.hbm.xml
     07:36:23,484 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/sstprophandler/Sstprophandler_DEV.hbm.xml
     07:36:23,486 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  com/cargosoft/csedi/data/sstneustart/Sstneustart_DEV.hbm.xml
     07:36:23,488 INFO  [HibernateManager              ] | Create new SessionFactory for: jdbc:informix-sqli://...

使用 hibernate 4.3.8-Final:

     07:38:04,749 INFO  [HibernateManager              ] | Verwende Mapping-Collection Datei : /de/cargosoft/edi/cargoservice/entities/mappings_dev.xml
     07:38:04,824 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/aart/Aart_DEV.hbm.xml
     07:38:05,249 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/abteilung/Abteilung_DEV.hbm.xml
     07:38:05,527 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/adr/Adr_DEV.hbm.xml
     07:38:05,792 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/adraesort/Adraesort_DEV.hbm.xml
     07:38:06,077 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/adrakte/Adrakte_DEV.hbm.xml
     ...
     07:40:14,119 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/zollanmtxt/Zollanmtxt_DEV.hbm.xml
     07:40:14,499 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/sstbasis/Sstbasis_DEV.hbm.xml
     07:40:14,746 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/sststruktur/Sststruktur_DEV.hbm.xml
     07:40:14,972 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/ssthandler/Ssthandler_DEV.hbm.xml
     07:40:15,211 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/sstproperty/Sstproperty_DEV.hbm.xml
     07:40:15,434 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/sstprophandler/Sstprophandler_DEV.hbm.xml
     07:40:15,657 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/sstneustart/Sstneustart_DEV.hbm.xml
     07:40:15,878 INFO  [HibernateManager              ] | Create new SessionFactory for: jdbc:informix-sqli://...

添加映射文件的方法如下所示:

 for (Node node : nodes) {
      Element element = (Element) node;
      String resource = element.attributeValue("resource");
      logger.info("Adding this resource to hibernate now          :  " + resource);
      configuration.addResource(resource);
 }

addResource 缺少时间。

我们还通过将映射元素直接移动到 hibernate.cfg.xml 文件中进行了尝试,但它需要同样的时间来启动。

我们相信 hibernate 正在验证 hibernate 3 没有验证的东西。

有没有人想解决这个问题?我们不能为每次测试运行等待 2 分钟。

非常感谢和许多问候, 豪克

更新

我将日志级别更改为“DEBUG”,现在是这样的:

我更改为日志级别进行调试,现在出来了:

  11:29:22,781 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/aart/Aart_DEV.hbm.xml
  11:29:22,782 INFO  [Configuration                 ] | HHH000221: Reading mappings from resource: de/cargosoft/edi/cargoservice/entities/aart/Aart_DEV.hbm.xml
  11:29:22,804 DEBUG [DTDEntityResolver             ] | Trying to resolve system-id [http://hibernate.org/dtd/hibernate-mapping-3.0.dtd]
  11:29:23,149 INFO  [HibernateManager              ] | Adding this resource to hibernate now          :  de/cargosoft/edi/cargoservice/entities/abteilung/Abteilung_DEV.hbm.xml
  ...

因此,DTDEntityResolver 似乎对每个实体大约需要 200 毫秒 - 400 毫秒。这将总结 500 个实体。

所以问题是,如何禁用它?

最佳答案

您需要更改所有 HBM 配置文件的 DTD:

http://hibernate.org/dtd/hibernate-mapping-3.0.dtd

到:

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

这就是 DTDEntityResolver 尝试定位 DTO 的方式:

public class DTDEntityResolver implements EntityResolver, Serializable {

    private static final String HIBERNATE_NAMESPACE = "http://www.hibernate.org/dtd/";
    private static final String OLD_HIBERNATE_NAMESPACE = "http://hibernate.sourceforge.net/";
    private static final String USER_NAMESPACE = "classpath://";

    public InputSource resolveEntity(String publicId, String systemId) {
        InputSource source = null; // returning null triggers default behavior
        if ( systemId != null ) {
            LOG.debugf( "Trying to resolve system-id [%s]", systemId );
            if ( systemId.startsWith( HIBERNATE_NAMESPACE ) ) {
                LOG.debug( "Recognized hibernate namespace; attempting to resolve on classpath under org/hibernate/" );
                source = resolveOnClassPath( publicId, systemId, HIBERNATE_NAMESPACE );
            }
            else if ( systemId.startsWith( OLD_HIBERNATE_NAMESPACE ) ) {
                LOG.recognizedObsoleteHibernateNamespace( OLD_HIBERNATE_NAMESPACE, HIBERNATE_NAMESPACE );
                LOG.debug( "Attempting to resolve on classpath under org/hibernate/" );
                source = resolveOnClassPath( publicId, systemId, OLD_HIBERNATE_NAMESPACE );
            }
            else if ( systemId.startsWith( USER_NAMESPACE ) ) {
                LOG.debug( "Recognized local namespace; attempting to resolve on classpath" );
                String path = systemId.substring( USER_NAMESPACE.length() );
                InputStream stream = resolveInLocalNamespace( path );
                if ( stream == null ) {
                    LOG.debugf( "Unable to locate [%s] on classpath", systemId );
                }
                else {
                    LOG.debugf( "Located [%s] in classpath", systemId );
                    source = new InputSource( stream );
                    source.setPublicId( publicId );
                    source.setSystemId( systemId );
                }
            }
        }
        return source;
    }

   ...

}

Hibernate 无法在 hibernate-core-4.3.8.Final.jar 中找到 hibernate-mapping-3.0.dtd 配置文件,因此它会递归通过你所有的类路径,因为你有一个巨大的项目,这就解释了为什么它开始这么慢。

关于java - 从 Hibernate 3 迁移到 4 会减慢启动速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28624325/

相关文章:

java - Spring/Hibernate 获取包含列表的对象列表

java - 尝试持久化实体时出现 DataException

javascript - 使用 STOMP 调用一项接受多个参数的服务

java - RoboGuice 提供错误

java - java Calendar.toInstant() 和 Instant.atZone(还有 Local/ZonedDateTime.ofInstant())中的不准确性/随机性

performance - 回放录制的脚本

python - python 的 any() 函数背后的技巧是什么?

java - 将节点插入二叉搜索树

C# if/return 或 if/return/else 更好?

java - Hibernate 3.3 兼容性 jdk 7