2015-02-20 11 views
6

stiamo provando a migrare il nostro progetto da Hibernate 3 a Hibernate 4. Tutto funziona bene, ma il problema è l'avvio.La migrazione da Hibernate 3 a 4 rallenta l'avvio

Non utilizziamo JPA, utilizziamo la sospensione diretta con il file xml e il mapping dei file.

<?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> 

La proprietà generated.mappingFile è una proprietà propria. All'avvio il file verrà caricato (dev.xml). Questo file è simile al seguente:

 <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" /> 

abbiamo ridotto il numero di mappatura in questo post. nel momento abbiamo più di mappature.

Con ibernazione 3 sono stati necessari 2 secondi per caricare tutti i mapping. Con hibernate 4 ci vogliono più di 2 minuti.

Ecco il file di log da 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://... 

con Hibernate 4.3.8-finale:

 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://... 

Il metodo che aggiunge i file di mapping simile a questa:

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); 
} 

La mancanza di tempo è su addResource.

Abbiamo anche provato spostando l'elemento di mappatura direttamente nel file hibernate.cfg.xml ma esso richiede lo stesso tempo all'avvio.

Crediamo che l'ibernazione sia la convalida di ciò che l'ibernato 3 non ha.

Qualcuno ha un'idea per risolvere questo problema? Non possiamo aspettare 2 minuti per ogni prova.

Grazie e tanti saluti, Hauke ​​

UPDATE

ho cambiato il livello di log di "DEBUG" e ora si tratta di questo:

ho cambiato a livello di log per eseguire il debug e questo è venuta fuori ora:

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 
    ... 

Così sembra che il DTDEntityResolver prende un circa 200ms - 400ms per ogni entità. Con 500 entità questo riassumerà.

Quindi la domanda è, come disabilitarlo?

+0

Stai utilizzando il runtime-enhancement? Hai provato a migliorare il build-time con "hibernate-enhance-maven-plugin" (aggiunto con 4.2.8)? http://java.dzone.com/articles/hibernate-bytecode-enhancement –

risposta

6

È necessario modificare la DTD di tutti i file di configurazione HBM da:

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

a:

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

Ecco come i DTDEntityResolver tenta di individuare il 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 non è in grado di individuare il file di configurazione hibernate-mapping-3.0.dtd nello hibernate-core-4.3.8.Final.jar e quindi passa in modo ricorsivo attraverso tutto il percorso di classe e, poiché un grande progetto, che spiega perché inizia così lentamente.

1

Una volta ho usato un trucco per saltare la convalida DTD durante l'analisi dei file XML, utilizzando il codice seguente. Il tuo caso è più complicato in quanto è necessario collegarlo al parser di configurazione di Hibernate. Ma potrebbe farti iniziare.

private boolean skipDtd = true; // TODO make configurable 

private EntityResolver dummyDtdResolver = new EntityResolver() 
{ 
    @Override 
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException 
    { 
     if (skipDtd && systemId.toLowerCase().endsWith(".dtd")) 
      return new InputSource(new StringReader("")); 
     return null; 
    } 
}; 

alcuni modi per usarlo:

  1. Da un DocumentBuilder

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder parser = dbf.newDocumentBuilder(); 
    parser.setEntityResolver(dummyDtdResolver); 
    ... 
    parser.parse(new File(xmlName));   
    
  2. Da un XmlReader

    SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); 
    saxParserFactory.setNamespaceAware(true); 
    XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader(); 
    xmlReader.setEntityResolver(dummyDtdResolver); 
    ... 
    new SAXSource(xmlReader, inputSource);