cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023
-
4 juin 2009 à 18:34
SankaWeon -
19 juin 2018 à 13:49
Bonjour.
J'essaie actuellement d'insérer de multiple lignes dans une table, en utilisant Hibernate.
Pour optimiser, je veux éviter de faire un save dans ma boucle. Je me suis donc dis que j'allais construire la requête à la main, et exécuter une requête SQL native.
Malheureusement, ça ne fonctionne pas. Voici un morceau simplifié de mon code qui pose problème:
Et l'erreur:
> Could not execute native bulk manipulation query
J'ai fait beaucoup de recherche, en essayant différente méthodes. Aucune ne fonctionne (en HQL Il n'y a pas INSERT INTO ... VALUES, en critéria, je n'ai rien trouvé de concluant, et les batch insert ne répondent pas à mon besoin). Auriez vous une solution fonctionnelle à ce problème ?
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 3 août 2009 à 15:12
J'ai oublié de vous répondre...
J'ai résolu mon problème en réalisant un script shell, qui balance des requêtes SQL. Pour un script de transformation hors code principal, c'est tout à fait acceptable.
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013129 4 juin 2009 à 19:21
Salut,
Quand tu décide d'utiliser un framework, il faut l'utiliser jusqu'au bout, sinon c'est le meilleur moyen pour rendre un compte immaintenable et bourré de bug !
Il est toujours plus facile de debugguer un code qui est homogène plutôt que de debugguer un code qui contient de multiples technologies...
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 4 juin 2009 à 19:39
Il y a la théorie et la réalité.
Je déteste devoir utiliser ce genre de bidouille, mais il n'est parfois pas possible de faire autrement. Je bosse sur une table absolument gigantesque (plusieurs millions d'entrées) qui doit en remplir une autre qui sera au moins 10 fois plus grande, tout en ayant de fortes contraintes de temps. De plus, ce n'est pas une partie du projet principal, mais un simple script de migration.
J'ai déjà écrit le script, avec du hibernate "propre", mais c'est encore beaucoup trop lent. La dernière optimisation qu'il me reste à faire, est celle d'insérer des lignes par paquets, et non une par une (concaténation de string pour former une seule requêtes, plus rapide que de faire un save dans une boucle). D'où le sujet de ma question.
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013129 4 juin 2009 à 20:39
A ce moment là utilise du pur JDBC et laisse de côté hibernate.
Fais un prepareStatement avec une Connection JDBC, et exécute tes requêtes d'insertions.
Cependant, je doute que tu obtienne un gain extrêmement important : Hibernate est vraiment très optimisé, et se rapproche des performances de JDBC, après, c'est le connector JDBC qui peut faire la différence : un connector natif pour l'OS utilisé étant toujours plus rapide qu'un connector codé en java !
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013129 4 juin 2009 à 21:32
Si bien sûr que si, hibernate permet de quasiment tout faire, sinon, il ne serait pas autant utilisé par les entreprises, mais vu que d'après toi même avec hibernate, tu n'es pas satisfait des performances et que tu préfères faire cà avec une requête SQL, je te donne les pistes.
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023124 4 juin 2009 à 22:24
J'ai fait beaucoup de recherche sur le net, et j'ai déjà lu ce lien.
Il ne réponds pas à mon besoin du tout, bien au contraire. Il sert à optimiser l'espace mémoire en flushant les requêtes. Je cherche justement à regrouper les requêtes, pour en faire le moins possibles. Néanmoins, je te remercie pour cette indication.
Si hibernate est capable de faire une insertion multi row, c'est à dire si celui ci est capable de générer une requête du type:
INSERT INTO table(a,b, c) VALUES(0,1,2,),(0,1,2,),(0,1,2,)(regroupement des values pour ne faire qu'une requête), alors je suis super intéressé.
Hibernate est un très bon produit, et je ne doute pas de ses performances, mais ma question initiale ne dit pas que celui ci ne convient pas, mais que je n'arrive pas à réaliser ce que je viens de décrire avec ce framework.
Bonjour cptpingu, je ressort une vielle question mais la réponse à ta question m'intéresse beaucoup aujourd'hui, je suis sur un même problème et je ne trouve toujours rien aujourd’hui pour y répondre. As-tu trouvé une réponse à ton problème d'insert avec hibernate ou du tout ? merci
Voir surtout la fin :
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlInsert = "insert into DelinquentAccount (id, name) select c.id, c.name from Customer c where ...";
int createdEntities = s.createQuery( hqlInsert )
.executeUpdate();
tx.commit();
session.close();
kirua12
Messages postés1155Date d'inscriptionsamedi 17 janvier 2004StatutMembreDernière intervention29 avril 20118 5 juin 2009 à 11:04
Salut,
hibernate a une vision objet et non table (c'est l'intérêt des framework de persistence). Donc lors de l'insertion, en version de base, c'est objet par objet.
Après l'optimisation dans ce cas, c'est le mode batch. On envoie n requêtes en 1 seule fois. Tu veux faire 1 requête avec n valeurs. Est ce vraiment différent ? As tu mesurer les performances ? c'est une simple question, j'ai toujours joué avec le mode batch et les perfs sont très bonnes (sauf dans le cas d'héritage entre tables où il faut bidouiller un peu) : par ex : qq centaines de milliers de lignes insérées en 2s. (oracle 10g)
hakker
Messages postés23Date d'inscriptionvendredi 15 février 2008StatutMembreDernière intervention20 février 2010 3 août 2009 à 14:32
hi dsl pour l'interruption. je vous demander est ce que on peu vraiment faire insertion ds la base sans faire un réquete on creer un objet et on y stock les nouvelles info désirer et puis avec un save. voila le pour mieux me comprenez:
public class MailDAO {
protected Session session;
public MailDAO(){this.session=this.session = HibernateUtil.getSessionFactory().getCurrentSession();}
public MailDAO(Session session){this.session=session;}
bon l'exécution marche sava mé ma table est vide c'est à dire y a pa d'insertion!
et dsl encore une fois pour le dérangement mercii d'avance.
nice working with u all guz!!
hakker
Messages postés23Date d'inscriptionvendredi 15 février 2008StatutMembreDernière intervention20 février 2010 4 août 2009 à 10:39
salut dsl kiura12 parce que j'ai pas donné ma question car j'ai déja écrir mon pb dans la page précedente mais c'est pa grave je vais le récrire.
hi dsl pour l'interruption. je vous demander est ce que on peu vraiment faire insertion dans la base sans faire une réquete.just on creer un objet et on y stock les nouvelles info désirer et puis avec un save. voila le pour mieux comprendre:
// ce code fais une insertion d 'un objet Mail dans la base BoiteMail.//
public class MailDAO {
protected Session session;
public MailDAO(){this.session=this.session = HibernateUtil.getSessionFactory().getCurrentSession();}
public MailDAO(Session session){this.session=session;}