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 :

[HQL] Update HQL sur une table avec Id composite


Sujet :

Hibernate Java

  1. #1
    Futur Membre du Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 6
    Points
    6
    Par défaut [HQL] Update HQL sur une table avec Id composite
    Bonjour à tous,

    Après de nombreuses recherches et aucun résultat, je me décide à vous faire part du problème que je rencontre actuellement sur Hibernate 3.

    Je cherche à exécuter un update en HQL sur une table dont l'Id est composite.

    Alors que j'arrive très bien à faire des updates sur des tables ou l'Id est simple, quand l'id est composite Oracle me remonte une erreur de syntaxe.

    Je pense que la requête générée n'est donc pas correcte.
    Malheureusement, je n'arrive pas à logger la requête qu'envoit hibernate pour m'en assurer.

    J'ai simplifié mon code au maximum et voici ce que cela donne:

    Tout d'abord la classe en question (sans les accesseurs pour réduire mon message):

    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
     
    public class Lot {
     
        private LotId id;
        private int etat;
        private String description;
     
        /** minimal constructor */
        public Lot(LotId id) {
            this.setId(id);
        }
     
        {...}
     
        }
    La classe LotId qui correspond à l'Id composite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class LotId implements Serializable{
     
        private int numeroLot;
        private int numeroTache;
     
        /** Creates a new instance of LotId */
        public LotId() {
            super();
        }
         {...}
    }
    le mapping de la classe:
    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
     
    <hibernate-mapping>
        <class name="vi.domain.Lot">
     
            <composite-id name="id" class="vi.domain.LotId">
                <key-property name="numeroLot" type="int">
                    <column name="NUMERO_LOT" precision="10" scale="0" />
                </key-property>
                <key-property name="numeroTache" type="int">
                    <column name="NUMERO_TACHE" precision="10" scale="0" />
                </key-property>
            </composite-id>
     
            <property name="etat" type="int">
                <column name="ETAT" />
            </property>
     
    {..}
    et enfin le code avec la requête HQL:

    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
     
     
        public static int updateEtat(Lot lot){
            String HqlQuery = "UPDATE Lot l SET l.etat = 0 WHERE l=:lot";
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
     
            Query query2 = session.createQuery(HqlQuery);
            query2.setEntity("lot",lot);
            int res = query2.executeUpdate();
            session.getTransaction().commit();
     
            if (session.isOpen()){
                session.close();
            }
            return res;
     
        }
    L'exception que je rencontre est la suivante:

    Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute update query.
    ...
    Caused by: java.sql.SQLException: ORA-00920: Opérateur relationnel non valide

    J'espère que l'un d'entre vous pourra m'aider car j'ai vraiment beaucoup cherché et ce problème est assez bloquant pour moi.

    Merci d'avance!!


    Eccoon

  2. #2
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    Ca me semble bizarre ta requete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    "UPDATE Lot l SET l.etat = 0 WHERE l=:lot";
    l est defini comme identifiant de table et ensuite tu fais une comparaison dessus , la syntaxe est incorrecte:
    peut etre tu veux faire l.etat = quelquechose ?

  3. #3
    Futur Membre du Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Merci beaucoup pour ta réponse.

    En j'utilise la même syntaxe pour mettre à jour une table ou l'id n'est pas composite (id générée par séquence par exemple).

    voici la requête qui fonctionne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     String HqlQuery = "UPDATE Volume v set v.numeroAgres = :agres where v=:volume";
    La logique est pourtant la même et mon update se fait correctement.
    La seule différence ,qui je pense pose problème, entre les 2 classes est le fait que la clé soit composite dans le premier cas.

    Je reste cependant ouvert à une proposition de syntaxe si tu en as une autre,
    sachant que je veux effectivement mettre à jour l'état de l'instance de la classe Lot qui m'est passé en paramêtre (le problème est ici réduit car l'update est en fait plus complexe mais je l'ai simplifié au maximum pour tenter de le résoudre ).

    Merci d'avance!


    Eccoon

  4. #4
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    Je dirais que dans ton cas, il faudrait ecrire un truc dans le style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String HqlQuery = "UPDATE Lot l SET l.etat = 0 WHERE l.numeroLot=:numlot and l.numeroTache=:numtache";
    et faire les setEntity adequats pour specifier numLot et numTache.
    En tous cas, je fais ca avec les composite_id et cela fonctionne bien.

  5. #5
    Futur Membre du Club
    Inscrit en
    Juin 2006
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    J'ai tenté la requête que tu m'as proposée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    String HqlQuery ="UPDATE Lot l SET l.etat = 0 WHERE l.numeroLot=:numlot and l.numeroTache=:numtache";
    Sans aucune modification, cela n'a pas fonctionné. En effet, la classe Lot ne porte pas les attributs numeroLot et numeroTache. Du coup Hibernate me renvoyait une erreur comme quoi la classe ne contenait pas ces attributs (logique ).
    Du coup j'ai modifié ma classe Lot pour lui ajouter ces attributs:

    Celle ci se présente comme ceci désormais:
    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
     
     
    public class Lot {
     
        private LotId id;
        private int etat;
        private String description;
        private int numeroLot;
        private int numeroTache;
     
        /** minimal constructor */
        public Lot(LotId id) {
            this.setId(id);
        }
     
        {...}
     
        }
    J'ai rajouté le mapping correspondant et maintenant cela fonctionne.

    Par contre du coup, les colonnes numero_lot et numero_tache sont mappés en double car elles sont mappés au niveau de l'id-composite et au niveau de la classe Lot.

    Quoi qu'il en soit je vais partir sur cette solution! Merci de m'avoir guider!
    Je reste néanmoins assez surpris qu'Hibernate ne soit pas capable de générer la requête de lui-même pour les id composites!

    @bientôt!

    Eccoon

  6. #6
    Membre expérimenté Avatar de willoi
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    1 355
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 355
    Points : 1 639
    Points
    1 639
    Par défaut
    ou sinon dans le premier cas il aurait fall ecrire comme condition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    WHERE l.id.numeroLot=:numlot and l.id.numeroTache=:numtache";
    j'avais pas fait attention que tu avais defini une classe pour ta cle composee.

Discussions similaires

  1. Update sur une table avec conditions
    Par tibss dans le forum Langage SQL
    Réponses: 8
    Dernier message: 08/07/2011, 17h13
  2. Requete SUM sur une table avec critère sur une autre
    Par wail00 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 21/05/2007, 16h58
  3. journalisation des updates, inserts sur une table
    Par philou28 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 28/04/2007, 16h07
  4. probleme de delete sur une table avec somation
    Par galaad666 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 23/10/2006, 16h44
  5. Réponses: 12
    Dernier message: 12/06/2006, 14h29

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