IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

Update sur Hibernate 2.1.2 sans charger les données


Sujet :

Hibernate Java

  1. #1
    Membre expérimenté
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Par défaut Update sur Hibernate 2.1.2 sans charger les données
    Bonjour à tous, dans un projet dont l'architecture m'est imposée, j'utilise un framework basé sur Hibernate 2.1.2.
    Je voudrais faire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    UPDATE transaction
    SET statut = 1
    WHERE id_client = 100
    A priori, grâce à Hibernate, c'est très simple, on charge les transactions dans un attribut List<Transaction> du client. On parcoure la liste des transactions pour modifier la valeur de leur statut une par une et on fait un update client...
    On va avoir quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Client client = (Client) session.load(Client.class, new Integer(100));
    for (Transaction transaction : client.getTransactions()) {
      transaction.setStatut(1);
    }
    session.update(client);
    Et ça marche très bien !
    Sauf quand mon client possède plusieurs dizaine de millier de transactions : 10minutes d'attente, environ. Alors que la requête ci-dessus en BDD prend quelques secondes.
    Je ne trouve pas de documentation sur Hibernate 2 et je n'arrive pas à faire cet UPDATE sans charger toutes les données.
    Un peu d'aide serait donc bienvenue, merci d'avance

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 964
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    String hqlUpdate = "update transaction t set t.statut= :newStatut where t.id_client = :clientID";
    int updatedEntities = session.createQuery( hqlUpdate )
            .setInteger( "newStatut", 1 )
            .setInteger( "clientID", 100 )
            .executeUpdate();
    tx.commit();
    session.close();

  3. #3
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Il est toujours possible de faire une requête SQL (donc de laisser faire le boulot à la BDD), que tu peux d'ailleurs écrire en HQL (de mémoire ça doit passer sur de la 2.1, à vérifier quand même).

    Sinon, forcément charger tous les objets dans ta JVM depuis la BDD, les modifier à la mano, et renvoyer ça à la BDD, ça va prendre du temps si ta liste est longue

  4. #4
    Membre expérimenté
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Par défaut
    Merci pour vos réponses à tous les deux, mais ça ne me suffit pas malheureusement. C'est bien pour ça que je précise la version d'Hibernate (2.1.2).
    @JeitEmgie il n'y a pas de méthode net.sf.hibernate.Query.executeUpdate() dans la version d'Hibernate que j'utilise et je crois que l'update en HQL a été l'une des grandes nouveautés de la version 3... Autrement dit je pense devoir passer par une requête SQL native, mais je me trompe peut-être ?
    @Rei Ichido je n'arrive pas à trouver de doc sur cette méthode net.sf.hibernate.Session.createSqlQuery(String, String, Class)
    Enfin, merci quand même

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Par défaut
    Citation Envoyé par karbos Voir le message
    Merci pour vos réponses à tous les deux, mais ça ne me suffit pas malheureusement. C'est bien pour ça que je précise la version d'Hibernate (2.1.2).
    @JeitEmgie il n'y a pas de méthode net.sf.hibernate.Query.executeUpdate() dans la version d'Hibernate que j'utilise et je crois que l'update en HQL a été l'une des grandes nouveautés de la version 3... Autrement dit je pense devoir passer par une requête SQL native, mais je me trompe peut-être ?
    @Rei Ichido je n'arrive pas à trouver de doc sur cette méthode net.sf.hibernate.Session.createSqlQuery(String, String, Class)
    Enfin, merci quand même
    J'avais un doute sur ton info, je viens de télécharger cette version, et mon doute s'est confirmé , voila les signatures des méthodes qui te seront utilises
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    /**
             * Create a new instance of <tt>Query</tt> for the given SQL string.
             * 
             * @param sql a query expressed in SQL
             * @param returnAlias a table alias that appears inside <tt>{}</tt> in the SQL string
             * @param returnClass the returned persistent class
             */
    	public Query createSQLQuery(String sql, String returnAlias, Class returnClass);
    ...
    /**
             * Create a new instance of <tt>Query</tt> for the given SQL string.
             * 
             * @param sql a query expressed in SQL
             * @param returnAliases an array of table aliases that appear inside <tt>{}</tt> in the SQL string
             * @param returnClasses the returned persistent classes
             */
    	public Query createSQLQuery(String sql, String[] returnAliases, Class[] returnClasses);
    ...
    /**
             * Obtain an instance of <tt>Query</tt> for a named query string defined in the
             * mapping file.
             *
             * @param queryName the name of a query defined externally
             * @return Query
             * @throws HibernateException
             */
    	public Query getNamedQuery(String queryName) throws HibernateException;
    ...
    /**
             * Create a new instance of <tt>Query</tt> for the given query string.
             *
             * @param queryString a Hibernate query
             * @return Query
             * @throws HibernateException
             */
    	public Query createQuery(String queryString) throws HibernateException;

  6. #6
    Membre expérimenté
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Par défaut
    Merci DevServlet, cette doc me manquait, effectivement.
    Je commence à comprendre comment construire ma requête, mais avec quoi je lance la mise à jour ? list() ou uniqueResult() ? C'est bizarre qu'il n'y ait pas d'antécédents de ce genre en Hibernate 2, non ?

  7. #7
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Par défaut
    Citation Envoyé par karbos Voir le message
    Merci DevServlet, cette doc me manquait, effectivement.
    Je commence à comprendre comment construire ma requête, mais avec quoi je lance la mise à jour ? list() ou uniqueResult() ? C'est bizarre qu'il n'y ait pas d'antécédents de ce genre en Hibernate 2, non ?
    Pas compris ta question. Que vx tu savoir? La methode à appeler pour faire une mise à jour? ou comment lancer l'execution de ta requete.

  8. #8
    Membre expérimenté
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Par défaut
    Ben il me semblait que c'était la même chose puisque ma requête est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE transaction SET statut = 1 WHERE id_client = 100

    Ce que je veux au final c'est que certaines données soient mises à jour sans avoir à charger toutes les lignes à modifier.
    J'arrive à modifier les données d'un objet (objet.update()), mais cela impose de le charger au préalable.
    Si je lance la requête, comme on ferait un SELECT, avec .list() ou .uniqueResult(), j'obtiens une HibernateException...
    D'où ma question : il me semble que j'arrive à former ma requête avec les méthodes dont tu m'as fourni la doc, mais comment lancer cette requête ?

  9. #9
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 938
    Par défaut
    Autant pour moi, essaie plutot list() alors, personnellement comme j'ai dit plus haut je n'ai pas encore utilisé cette version, j'ai juste télécharge l'API et consulté les sources,effectivement comme tu dis y'a plus le executeUpdate() sur la classe Session.

  10. #10
    Membre expérimenté
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Par défaut
    Citation Envoyé par DevServlet Voir le message
    Autant pour moi, essaie plutot list() alors, (...)
    Nan, ça marche pas... J'ai une HibernateException.
    Je reste donc bloqué : j'ai le choix entre un truc long et la possibilité de contourner le framework Hibernate 2 et d'attaquer directement ma base en JDBC... au risque de créer des failles de sécurité et des problèmes ailleurs.
    Je préfère ne rien faire pour l'instant, je laisse ça de côté.
    Merci quand même

  11. #11
    Membre expérimenté Avatar de mOuLi
    Homme Profil pro
    Développeur Java
    Inscrit en
    Avril 2008
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Avril 2008
    Messages : 170
    Par défaut
    Même si effectivement la requête SQL semble être la solution la plus performante, il est possible que d'autres facteurs entrent en compte dans ton problème de performance : je pense notamment au remplissage du cache L1.

    Il serait peut-être intéressant :
    1/ d'intégrer des appels aux opérations flush (pour déclencher les UPDATE) et clear (pour vider le cache L1) sur la session Hibernate. L'idée est de découper ta boucle de traitement en lots (par exemple déclenchement des flush et clear toutes les 20 itérations).
    2/ de préciser une valeur à l'option hibernate.jdbc.batch_size dans la configuration Hibernate pour optimiser l'application des lots d'UPDATE définis ci-dessus. L'idéal étant d'utiliser "la taille du lot de traitement" (20 dans mon exemple).

  12. #12
    Membre expérimenté
    Avatar de karbos
    Inscrit en
    Novembre 2008
    Messages
    155
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 155
    Par défaut
    Je vais essayer ça, merci mOuLi.
    Par contre je n'ai toujours pas réussi à faire un update en sql natif... j'hésite à clore le sujet...

Discussions similaires

  1. Réponses: 1
    Dernier message: 23/07/2015, 11h28
  2. Réponses: 9
    Dernier message: 07/01/2011, 22h50
  3. Ecrire sur fichier sans effacer les données
    Par kimikimi dans le forum Débuter
    Réponses: 2
    Dernier message: 01/07/2010, 10h56
  4. Réponses: 13
    Dernier message: 14/09/2005, 17h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo