2017-09-03 1 views
0

J'ai un problème avec hibernate + java. J'ai une classe qui prend un fichier, l'analyse en CSVRecord et ensuite par processRecord() convertit chaque ligne en un objet (classA), puis j'essaie de trouver cet objet dans ma DB, si j'avais l'objet "else" Je l'enregistre pour la première fois. Après 1000 lignes traitées, je valide la transaction, nettoie la session et recommence la transaction. Le problème est lorsque commencer à traiter le fichier (1 Million d'enregistrements) la mémoire Java consommer commencer à grandir beaucoup (2 Go) et à la fin ne libèrent pas, donc si j'ai besoin de la méthode traiter un autre fichier je n'ai pas de mémoire, Je n'ai jamais eu d'exception de mémoire, car j'ai toujours de la mémoire, mais ça ne va pas être la même chose sur le serveur. J'essaie de faire le même code en utilisant flush() et clair(), mais n'a pas millepertuis ni, Le code est quelque chose comme ceci:Hibernate, enregistrer 1Millon entités, consomment beaucoup de mémoire

db = new DB(); 
db.open(); 
trn = db.session().beginTransaction(); 

for (CSVRecord line : lines) { 
     try { 
      if ((classA = processRecord(line)) != null) { 
      classB b = findObject(classA); 

      if (b != null) { 
       db.session().update(b); 
      } else { 
       db.session().save(classA); 
      } 

      if (recordNumber % 1000 == 0) { 
       trn.commit(); 
       db.session().clear(); 
       trn = db.session().beginTransaction(); 
      } 

      recordNumber++; 
      } 
     } catch (Exception e) { 
       e.printStackTrace(); 
     } 
} 

db.close(); 
+0

peut-être une solution facile est de simplement gérer 1000 par transaction et fermer et commencer un nouveau etc .. ?? –

+0

Oui, je l'ai essayé et en quelque sorte cela fonctionne, mais l'idée n'a pas été acceptée par le chef de projet, je ne suis pas bon avec l'idée ni parce que je vais ouvrir et fermer trop de fois la DB. – Eber

+0

Il existe des solutions en ligne, en streaming le fichier. J'ai trouvé ceci par exemple: http://www.baeldung.com/java-read-lines-large-file –

Répondre

0

Utilisez une session sans état car il ne dispose pas d'un persistance contexte cache qui améliore les performances par rapport à la méthode que vous utilisez actuellement

StatelessSession session = sessionFactory.openStatelessSession(); 
Transaction tx = session.beginTransaction(); 
for (int i=0; i<100000; i++) { 
    session.insert(yourentiry); 
} 
tx.commit(); 
session.close(); 
+0

Sans aucun doute je vais lire et essayer! Demain je vous laisse savoir comment c'était – Eber

+0

Malheureusement, ne fonctionnait pas, consommant toujours beaucoup de mémoire RAM ... – Eber