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 :

[hibernate] one-to-many et clé etrangère


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    370
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Avril 2006
    Messages : 370
    Par défaut
    Bonjour,

    Voilà, Hibernate me pose encore et toujours des soucis, en effet je n'arrive pas a mapper une relation one-to-many

    Contexte un utilisateur possède une collection (un set) de fichiers

    la table utilisateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE utilisateur
    (
      id int2 NOT NULL,
      nom varchar(20) NOT NULL,
      CONSTRAINT "User_pkey" PRIMARY KEY (id)
    ) 
    WITHOUT OIDS;
    ALTER TABLE utilisateur OWNER TO postgres;
    la table fichier :
    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
     
    CREATE TABLE fichiers
    (
      id int2 NOT NULL,
      nom varchar(50),
      id_utilisateur int2,
      CONSTRAINT fichiers_pkey PRIMARY KEY (id),
      CONSTRAINT fichiers_id_utilisateur_fkey FOREIGN KEY (id_utilisateur)
          REFERENCES utilisateur (id) MATCH SIMPLE
          ON UPDATE NO ACTION ON DELETE NO ACTION
    ) 
    WITHOUT OIDS;
    ALTER TABLE fichiers OWNER TO postgres;
    GRANT ALL ON TABLE fichiers TO postgres;
    GRANT ALL ON TABLE fichiers TO public;
    le mapping user :
    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
    <hibernate-mapping>
     
        <class name="metier.User" table="utilisateur">
     
            <id name="id" type="integer">
                 <column name="id"/>
                 <generator class="sequence" />
             </id>
     
            <property name="nom" type="string"> </property>
     
            <set name="fichiers" cascade="all" lazy="true">
                <key column="id_utilisateur"></key>
                <one-to-many class="metier.Fichier"></one-to-many>    
            </set>
     
        </class>
     
        </hibernate-mapping
    le test :
    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
    Session session = HibernateUtil.currentSession();
            Transaction tx = session.beginTransaction();
     
            User us = new User();
            us.setNom("Robert");
     
            Fichier fic1 = new Fichier();
            fic1.setNom("test.doc");
            Fichier fic2 = new Fichier();
            fic2.setNom("ouille.jpg");
     
            us.getFichiers().add(fic1);
            us.getFichiers().add(fic2);
            session.save(us);
     
            tx.commit();
     
            System.out.println("Enregistrement effectué");
            System.out.println("Recuperation des données");
     
            List listUser = session.createQuery("from utilisateur").list();
            Iterator it = listUser.iterator();
            while(it.hasNext())
            {
                User util = (User)it.next();
                System.out.println("L'utilisateur"+util.getNom()+"possède les fichiers suivants :");
                for(Fichier f : util.getFichiers())
                {
                    System.out.println(f.getNom());
                }
            }
     
            HibernateUtil.closeSession();
        }
    Et un extrait de l'erreur généré :
    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: select nextval ('hibernate_sequence')
    Hibernate: insert into utilisateur (nom, id) values (?, ?)
    Hibernate: insert into fichiers (nom, id_utilisateur, id) values (?, ?, ?)
    Hibernate: insert into fichiers (nom, id_utilisateur, id) values (?, ?, ?)
    15:00:16,409 WARN JDBCExceptionReporter:71 - SQL Error: 0, SQLState: null
    15:00:16,409 ERROR JDBCExceptionReporter:72 - L'élément du batch 0 insert into fichiers (nom, id_utilisateur, id) values (test.doc, 0, 54) a été annulé. Appeler getNextException pour en connaître la cause.
    15:00:16,409 WARN JDBCExceptionReporter:71 - SQL Error: 0, SQLState: 23503
    15:00:16,409 ERROR JDBCExceptionReporter:72 - ERROR: insert or update on table "fichiers" violates foreign key constraint "fichiers_id_utilisateur_fkey"
    Détail : Key (id_utilisateur)=(0) is not present in table "utilisateur".
    15:00:16,419 ERROR AbstractFlushingEventListener:300 - Could not synchronize database state with session
    org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    Pourquoi prend-il 0 comme id utilisateur ? bizarre

    Voila toujours avec mes déboires face a Hibernate mais je suis têtu, j'y arriverai ...

    PS : si j'enlève la contrainte foreign key sur la colonne id_utilisateur de la table fichiers alors l'insertion marche. Mais la récupération foire sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List listUser = session.createQuery("from utilisateur").list();
    avec l'erreur suivante :
    Exception in thread "main" java.lang.NoClassDefFoundError: antlr/ANTLRException
    at org.hibernate.hql.ast.ASTQueryTranslatorFactory.createQueryTranslator(ASTQueryTranslatorFactory.java:35)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:72)
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:54)
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:71)
    at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:133)
    at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:112)
    at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1583)
    at test.Test.main(Test.java:44)
    Quelqu'un saurait-il m'expliquer comment résoudre ce problème ?

    Merci d'avance pour votre aide.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    160
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 160
    Par défaut
    bonjour,

    enleve dans le fichier de mapping dans la definition de l'ID, le generator est dit moi ce qui se passe, j'avais à peu pres le meme probleme et j'essayer tout jusqu'à ce que j'enleve le generator surtout que les messages d'erreurs m'avaient brouillé un peu le chemin.
    donc essaie ça et reponds moi

  3. #3
    Membre chevronné

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2002
    Messages
    346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 346
    Par défaut
    Salut,

    Quelques éléments/questions :
    - As-tu bien créé ta séquence (apparament, hibernate utilise une séquence appelé hibernate_sequence).
    - Quelle est la base de données que tu utilise : le generator sequence est pour oracle et postgres (de tête, à vérifier), mysql par exemple en utilise un autre
    - Précise le nom de ta séquence au niveau de la définition de ton générator c'est toujours mieux (regarde la doc hibernate).
    - La librairie antlr.jar est-elle bien dans ton classpath
    java.lang.NoClassDefFoundError: antlr/ANTLRException - Essaye de mettre dans ton hibernate.cfg.xml la propriété suivante celà désactive l'utilisation du batch de hibernate qui peut poser problème avec certaine version de base de données. De plus tu saura exactement où se situe ton problème les requête étant réalisé en temps réelle (en non en batch)
    <property name="hibernate.jdbc.batch_size">0</property>

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    370
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Avril 2006
    Messages : 370
    Par défaut
    J'utilise une base postgre 8.1, la sequence est bien défini dans la base.
    Précision : l'insertion d'un utilisateur seul sans fichier fonctionne, l'insertion d'un utilisateur avec des fichiers sans la contraine clé étrangère sur la colonne id_utilisateur de la table fichiers fonctionne.

    Mais pas moyen d'inserer ce même test qi la contrainte est placé sur la colonne id_utilisateur de la table fichiers.

    J'ai rajouter la librairie antlr mais cela ne solutionne pas le pb il me retourne toujours :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not insert: [metier.Fichier]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2078)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2427)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at test.Test.main(Test.java:39)
    Caused by: org.postgresql.util.PSQLException: ERROR: insert or update on table "fichiers" violates foreign key constraint "fichiers_id_utilisateur_fkey"
      Détail : Key (id_utilisateur)=(0) is not present in table "utilisateur".
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1512)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1297)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:188)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:430)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:346)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:300)
        at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2062)
        ... 11 more
    11:38:01,222  WARN JDBCExceptionReporter:71 - SQL Error: 0, SQLState: 23503
    11:38:01,222 ERROR JDBCExceptionReporter:72 - ERROR: insert or update on table "fichiers" violates foreign key constraint "fichiers_id_utilisateur_fkey"
      Détail : Key (id_utilisateur)=(0) is not present in table "utilisateur".
    11:38:01,222 ERROR AbstractFlushingEventListener:300 - Could not synchronize database state with session
    org.hibernate.exception.ConstraintViolationException: could not insert: [metier.Fichier]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2078)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2427)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:51)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:139)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at test.Test.main(Test.java:39)
    Caused by: org.postgresql.util.PSQLException: ERROR: insert or update on table "fichiers" violates foreign key constraint "fichiers_id_utilisateur_fkey"
      Détail : Key (id_utilisateur)=(0) is not present in table "utilisateur".
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1512)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1297)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:188)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:430)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:346)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:300)
        at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2062)
        ... 11 more
    Donc d'apres ce que j'en comprend il cherche a inserer les fichiers pour l'utilisateur d'id 0 qui bien sur n'existe pas ...
    Mais pourquoi agit t'il ainsi ??

  5. #5
    Membre chevronné

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2002
    Messages
    346
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 346
    Par défaut
    As tu essayer de mettre ça dans ton hibernate.cfg.xml?
    <property name="hibernate.jdbc.batch_size">0</property>

    Sinon, apparement il essaye de t'insérer fichier avant d'avoir executer la séquence.
    Essaye donc de faire un save sur ton user, puis ensuite de lui lier les fichier et de refaire un saveOrUpdate sur ton user

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    370
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Avril 2006
    Messages : 370
    Par défaut
    La propriete a été mise en effet,

    je vien de tester comme ca je ne sait pas si c'est ce que tu voulai faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    User us = new User();
            us.setNom("Robert");
            session.save(us);
     
            Fichier fic1 = new Fichier();
            fic1.setNom("test.doc");
            Fichier fic2 = new Fichier();
            fic2.setNom("ouille.jpg");
     
            us.getFichiers().add(fic1);
            us.getFichiers().add(fic2);
     
            session.saveOrUpdate(us);
    Mais toutjours la même erreur ...

    Je commence a desespérer la cela fait maintenant 5jours que j'essai de faire fonctionner cet exemple tout simple avant de l'utiliser dans mon application (et vu qu'il s'agit de la persistance ca m'ennuie quand même beaucoup pour mon projet)

Discussions similaires

  1. Problème hibernate one-to-many / many-to-one
    Par valkeke dans le forum Hibernate
    Réponses: 4
    Dernier message: 02/04/2014, 14h06
  2. Mapping Hibernate one-to-many
    Par [ric] dans le forum Hibernate
    Réponses: 1
    Dernier message: 16/09/2010, 11h04
  3. [Hibernate] Relation one to many
    Par BRAUKRIS dans le forum Hibernate
    Réponses: 2
    Dernier message: 23/08/2006, 11h51
  4. [Hibernate][one-to-one] clé etrangère avec des blancs
    Par seb_fou dans le forum Hibernate
    Réponses: 1
    Dernier message: 06/04/2006, 10h28
  5. [hibernate] relation one-to-many avec plusieurs clés
    Par seb_fou dans le forum Hibernate
    Réponses: 6
    Dernier message: 16/03/2006, 14h47

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