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 :

Erreur MySQL suite au mapping d'une collection


Sujet :

Hibernate Java

  1. #1
    Membre actif
    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
    Points : 223
    Points
    223
    Par défaut Erreur MySQL suite au mapping d'une collection
    Bonjour,

    Voila, j'ai un objet Contact qui possède une liste (un HashSet) de Phone.

    Utilisation standard d'hibernate, je cherche à ajouter un Phone à mon Contact de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //Recup du bean par Spring 
    IContactDao dao = (IContactDao) new XmlBeanFactory(new ClassPathResource("applicationContext.xml")).getBean("dao");
    		Phone phone = new Phone("06.25.45.49.12");
    		Contact contact1 = dao.getContactById(1);
    		contact1.getPhones().add(phone);
    Sauf qu'à l'execution j'obtiens l'erreur MySQL suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ATTENTION: SQL Error: 1054, SQLState: 42S22
    8 juin 2007 09:52:30 org.hibernate.util.JDBCExceptionReporter logExceptions
    GRAVE: Unknown column 'phones1_.phone' in 'field list'
    Mes 2 mapping :

    Contact.hbm.xml
    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
     
    <hibernate-mapping package="entities">
    	<class name="Contact" table="contacts" lazy="false">
    		<id name="id" column="id">
    			<generator class="increment"></generator>
    		</id>
    		<property name="nom" />
    		<property name="prenom" />
    		<property name="surnom" />
    		<property name="birthDate" />
    		<property name="adresse" />
    		<property name="codePostal" />
    		<property name="city" />
    		<set 	name="phones" 
    				lazy="false" 
    				inverse="true"
    				cascade="all-delete-orphan" 
    				order-by="description asc" 
    				outer-join="true" >
     
    			<cache usage="read-write" />
     
    			<key column="id"></key>
     
    			<one-to-many class="entities.Phone" />
     
    		</set>
    	</class>
    </hibernate-mapping>
    Phone.hbm.xml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    <hibernate-mapping package="entities">
    	<class name="Phone" table="phones" lazy="false">
    		<id name="id" column="id">
    			<generator class="increment"></generator>
    		</id>
    		<property name="phone" />
    		<many-to-one name="contact" class="entities.Contact"
    			cascade="none" outer-join="auto" update="true" insert="true"
    			column="id_contact" />
    	</class>
    </hibernate-mapping>
    et mes 2 tables dans MySQL :
    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
     
    CREATE TABLE `contacts` 
    (`id` int(3) NOT NULL,
    `nom` varchar(25) default NULL, 
    `prenom` varchar(25) default NULL, 
    `surnom` varchar(25) default NULL,
    `birthdate` date default NULL,
    `adresse` varchar(150) default NULL,
    `codePostal` int(11) default NULL, 
    `city` varchar(50) default NULL,
    PRIMARY KEY  (`id`)) 
    ENGINE=InnoDB DEFAULT CHARSET=latin1;
     
    CREATE TABLE `phones` 
    (`id` int(3) NOT NULL,
    `phone_number` varchar(14) NOT NULL,
    `id_contact` int(3) NOT NULL,
    PRIMARY KEY  (`id`),
    KEY `fk_phone_contact` (`id_contact`),CONSTRAINT `fk_phone_contact` FOREIGN KEY (`id_contact`) REFERENCES `contacts` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION )
    ENGINE=InnoDB DEFAULT CHARSET=latin1;
    Je n'arrive pas du tout a localiser d'où pourrait provenir l'erreur, d'où provient ce phone1_.phone ?

  2. #2
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Les attributs de tes classes correspondent-ils bien à ceux de tes mappings ?

  3. #3
    Membre actif
    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
    Points : 223
    Points
    223
    Par défaut
    Normalement oui pas de probleme la dessus, le set de mon Contact s'appelle bien phones, le Contact dans phone s'appelle bien contact, et la colonne dans ma table phones s'appelle bien id_contact.

  4. #4
    Membre régulier
    Inscrit en
    Août 2005
    Messages
    159
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 159
    Points : 97
    Points
    97
    Par défaut
    Bonjour K-kai. Le problème vient du mapping de phone. Le champ phone de table phone a comme nom phone_number.

    Quant je regarde le mapping de phon je vois
    <property name="phone" />. En fait hibernate, lorsqu'on ne précise pas de column genere un sql avec comme nom de champ bd le nom de ton attribut (phone).

    Ton mapping pour etre correcte devrait etre

    <property name="phone" column="phone_number" />
    Essai ca et on verra
    Bye

  5. #5
    Membre actif
    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
    Points : 223
    Points
    223
    Par défaut
    Euh toute mes confuses j'avais tout vérifié sauf ce champs la ... Et oui je savais bien que pour ne pas spécifier la colonne dans le fichier de mapping, il faut absoluement qu'elles aient le même nom

    Merci merci

    Par contre petit soucis voila mon code de l'ajout d'un phone a un contact :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Contact contact1 = dao.getContactById(1);
    		contact1.getPhones().add(phone);
    		dao.updateContact(contact1);
    et je me prends comme erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ATTENTION: SQL Error: 1048, SQLState: 23000
    8 juin 2007 11:56:39 org.hibernate.util.JDBCExceptionReporter logExceptions
    GRAVE: Column 'id_contact' cannot be null
    Je pensais pourtant que c'était hibernate qui devait s'occuper de donner à mon phone le bon attribut mais visiblement non ? Peut être un soucis dans mon mapping ?

    Question subsiaire :

    J'utilise conjointement à Hibernate le framework Spring qui me fourni via le HibernateTemplate les methode de persistance sur mon objet contact. Hors vu que chaque fonction manage la session et la transaction, je ne peut pas faire gérer la persistance simplement avec ma ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    contact1.getPhones().add(phone);
    car le lazy loading est à false (objet contact orcement detaché) j'ai bon ?
    Maintenant quand je passerai à la couche supérieur (service) et déclarerai une methode d'ajout de numero géré à l'aide d'une transaction me sera t'il possible de le faire ?

  6. #6
    Membre régulier
    Inscrit en
    Août 2005
    Messages
    159
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 159
    Points : 97
    Points
    97
    Par défaut
    Essaie ca
    Contact contact1 = dao.getContactById(1);
    phone.setContact(contact1);
    contact1.getPhones().add(phone);
    dao.updateContact(contact1);

    C'est ce qui est en gras que j'ai ajoute. Ca devrait marcher.


    NB : J'espère que ton phone est deja mappe en bd (Ton portion de code ne nous donne pas sa provenance).

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Points : 495
    Points
    495
    Par défaut
    Ouh là !! ouedmouss est passé avant moi, mais bon, je garde quand même ce que j'ai écrit...

    Citation Envoyé par K-Kaï
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ATTENTION: SQL Error: 1048, SQLState: 23000
    8 juin 2007 11:56:39 org.hibernate.util.JDBCExceptionReporter logExceptions
    GRAVE: Column 'id_contact' cannot be null
    Je pensais pourtant que c'était hibernate qui devait s'occuper de donner à mon phone le bon attribut mais visiblement non ? Peut être un soucis dans mon mapping ?
    Non, hibernate ne va pas s'occuper de donner le bon attribut à ton phone, c'est à toi de le lui indiquer. Donc tu dois avoir ceci dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    contact1.getPhones().add(phone);
    phone.setContat(contact1);
    C'est ce qui permettra à hibernate d'appliquer le "cascading" sur l'objet phone.
    D'ailleurs, la doc officielle de hibernate conseille d'ajouter une méthode qui contient ces deux lignes de code pour faciliter les choses. Tu pourrais ajouter dans ta classe Contact une méthode addPhone() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public void addPhone(Phone phone) {
        phone.setContact(this);
        this.getPhones().add(phone);
    }
    Ce qui ramènerait ton code d'ajout d'un phone à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Contact contact1 = dao.getContactById(1);
    contact1.addPhone(phone);
    dao.updateContact(contact1);
    Voilà, j'espère que ça aide.
    Quant à ta question sur Spring, je n'ai pas vraiment compris...

  8. #8
    Membre actif
    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
    Points : 223
    Points
    223
    Par défaut
    D'accord je ne me rappelai plus de ça j'étais persuadé que ca fonctionnait comme je le sous entendais ( 1an que je n'ai pas touché à hibernate).
    Merci bien

    Ma question autour de Spring etait sur la ligne en dessous, le update que je suis obligé de faire à cause de la gestion des sessions par Spring. Je me demandais si en placant ensuite ma methode complète dans une classe service avec gestion des transactions je pourrais m'en passer (puisque logiquement la session sera conservé par Spring tout le long de la transaction).

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par K-Kaï
    Ma question autour de Spring etait sur la ligne en dessous, le update que je suis obligé de faire à cause de la gestion des sessions par Spring. Je me demandais si en placant ensuite ma methode complète dans une classe service avec gestion des transactions je pourrais m'en passer (puisque logiquement la session sera conservé par Spring tout le long de la transaction).
    Effectivement, en faisant remonter ces lignes de code dans une méthode d'une classe service avec gestion des transactions par Spring, tu n'as plus besoin de l'appel explicit à dao.updateContact(). Etant donné que Spring associe la session hibernate à la transaction en cours, la mise à jour des modifications est effectuée automatiquement au commit de la transaction. Essaie pour voir ce que ça donne, mais en tout cas c'est ce que j'ai toujours fait et ça marche.

Discussions similaires

  1. Erreur dans le mapping d'une collection
    Par gégé140488 dans le forum JPA
    Réponses: 1
    Dernier message: 06/10/2011, 16h21
  2. Réponses: 0
    Dernier message: 26/10/2009, 15h02
  3. [Hibernate] mapping d'une collection
    Par Jorus dans le forum Hibernate
    Réponses: 22
    Dernier message: 01/12/2008, 17h16
  4. [SQL] Erreur mysql suite à une requête
    Par vimarty dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 03/01/2008, 09h27
  5. [Debutant]Mapping pour une collection
    Par maxattack dans le forum Hibernate
    Réponses: 14
    Dernier message: 14/06/2007, 10h59

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