-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 
Author Message
 Post subject: Problème de mappig many-to-one property-ref
PostPosted: Wed Sep 14, 2005 1:21 pm 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
Bonjour,

Voila je débute avec hibernate, et j'ai un problème de mapping, et malgrés mes recherches je n'ai pas réussis à trouver de réponsecorrespondant à mon cas, pourtant simple.

J'ai 2 tables, Personne et Adresse,
Une relation uni-directionnelle : une personne a une adresse au maximum mais peu ne pas en avoir.

Mon but est que quand je sauvegarde/delete une personne, hibernate sauvegarde automatiquement l'adresse.

Mes fichier de mapping donne ca :

pour la personne :
Code:
<hibernate-mapping>
    <class
        name="fr.appli.persistance.dao.hibernate.PersonnePersistant"
        table="Personne"
        dynamic-update="false"
        dynamic-insert="false"
    >

property
            name="nom"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="NOM"
        />

property
            name="prenom"
            type="java.lang.String"
            update="true"
            insert="true"
            access="property"
            column="PRENOM"
        />

<many-to-one
            name="adr"
            class="fr.appli.persistance.dao.hibernate.AdressePersistant"
            cascade="all"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            property-ref="idAdr"
            column="IDADR"
        />
  </class>
</hibernate-mapping>


pour l'adresse rien de spécial :

Code:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
    <class
        name="fr.appli.persistance.dao.hibernate.AdressePersistant"
        table="ADRESSE"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="idAdr"
            column="IDADR"
            type="java.lang.String"
        >
            <generator class="assigned">
            </generator>
        </id>
  </class>
</hibernate-mapping>



Mon problème est que quand je lance jboss(3.2.5), après avoir déployé mon appli, ca plante(sans trace), et finalement je ne voit que les log4j d'erreur quand je veut fermer la session et qu il me sort :

Code:
java.lang.NoClassDefFoundError
   at fr.appli.persistance.transaction.TransactionFacade.fermerSession(TransactionFacade.java:197)


Si j'enlève le:
Code:
property-ref="idAdr"
, hibernate tente d'insérer la personne avant l'adresse, ce qui lance une erreur (normal puisque l'id de l'adresse n'est pas encore en base).

Si je sauvegarde l'adresse avant la personne ca marche, mais j'aimerais faire la chose en une seule fois.

Si j'essaye un one-to-one, et que la personne n'a pas d'adresse, il met quand même la premiere adresse de ma table adresse dans mon objet PersonnePersistant.

Si vous aviez une idée merci.

Hibernate version:2.1.6

Name and version of the database you are using:Oracle9.2

JRE et IDE : 1.4.2, eclipse 3.0.1


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 14, 2005 1:47 pm 
Pro
Pro

Joined: Fri Sep 02, 2005 4:21 am
Posts: 206
Location: Vienna
Code:
java.lang.NoClassDefFoundError

semble indiquer qu'il manque un fichier jar - mais lequel?

Je te conseillerais d'écrire un test JUnit pour être sûr que tout est correct - ce que je crois. Si c'est le cas il ne reste plus qu'à faire du debugging dans JBoss pour savoir quelle classe manque - et en déduire quel jar est en cause.

Erik


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 4:55 am 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
Bonjour,

merci d'avoir répondu.
Je vais essayer de faire ce que tu me conseil, mais je pensais plus à un problème de mapping, vu que si j'enlève property-ref et que je sauvegarde l'adresse avant la personne , ca marche, je n'est plus de :

Code:
java.lang.NoClassDefFoundError


J'avait lu des postes ou il manquait des dom4j et autre jar dans le classpath, mais chez moi ils y sont bien.

Je pense que ca vient du mapping car apparement je plante juste au moment de faire un
Code:
Session s = HibernateUtil.currentSession();


il lance le parsing sur les fichiers hbm.xml, puit il plante.

La trace :

Code:
10:40:42,000 INFO  [Configuration] Mapping resource: fr/appli/persistance/dao/hibernate/AdressePersistant.hbm.xml
10:40:42,046 INFO  [Binder] Mapping class: fr.appli.persistance.dao.hibernate.AdressePersistant -> ADRESSE
10:40:42,375 INFO  [Configuration] Mapping resource: fr/appli/persistance/dao/hibernate/PersonnePersistant.hbm.xml
10:40:42,421 INFO  [Binder] Mapping class: fr.appli.persistance.dao.hibernate.PersonnePersistant -> PERSONNE
10:40:42,515 INFO  [Configuration] Configured SessionFactory: null
10:40:42,515 INFO  [Configuration] processing one-to-many association mappings
10:40:42,515 INFO  [Configuration] processing one-to-one association property references
10:40:42,546 INFO  [STDOUT] 2005-09-15 10:40:42,546 DEBUG TransactionFacade.fermerSession - Fermeture de la session courante
10:40:42,578 ERROR [Engine] StandardContext[/]StandardWrapper.Throwable
java.lang.NoClassDefFoundError
   at fr.appli.persistance.transaction.TransactionFacade.fermerSession(TransactionFacade.java:197)
   at fr.appli.domaine.transaction.TransactionFacade.fermerSession(TransactionFacade.java:79)
...
10:40:42,578 ERROR [Engine] StandardContext[/testhibernate]Servlet /testhibernate threw load() exception
javax.servlet.ServletException: Servlet.init() for servlet init threw exception
   at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1061)
...
10:40:42,578 ERROR [Engine] ----- Root Cause -----
java.lang.NoClassDefFoundError
   at fr.appli.persistance.transaction.TransactionFacade.fermerSession(TransactionFacade.java:197)
....


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 6:37 am 
Pro
Pro

Joined: Fri Sep 02, 2005 4:21 am
Posts: 206
Location: Vienna
Sylad wrote:
Je pense que ca vient du mapping ...

C'est possible, mais alors seulement indirectement car une erreur de mapping "normale" n'a jamais (je veux dire que je n'ai jamais rien vu de tel) produit une NoClassDefFoundError. De plus, quand je vois le trace, je crois qu'Hibernate a déjà lu le mapping - sans encombres.

Pourrais-tu poster la partie de ton programme autour de la la ligne
Code:
fr.appli.persistance.transaction.TransactionFacade.fermerSession(TransactionFacade.java:197)

À mon avis c'est par là qu'il faut commencer à chercher.

Erik


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 8:17 am 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
Voila le code :

Code:
    /**
     * Ferme la session courante
     * @throws TechniqueErreur
     */
    public static void fermerSession() throws TechniqueErreur {
        if (log.isDebugEnabled()){
            log.debug("Fermeture de la session courante");
        }
        try {
            transaction.set(null);                     // Libère une éventuelle transaction stockée
            Session s = HibernateUtil.currentSession();
            if (s !=null) {
                if (log.isDebugEnabled()){
                    log.debug("Récupération de la session courante");
                }                               
                HibernateUtil.closeSession();
                if (log.isDebugEnabled()){
                    log.debug("Fermeture de la session courante");
                }               
            } else {
                if (log.isDebugEnabled()){
                    log.debug("Aucune session courante");
                }               

            }
        } catch (HibernateException he) {
            log.error("Erreur Hibernate : "+he.getMessage());
           
            TechniqueErreur techErr = new TechniqueErreur();
            techErr.setCode(ConstantesErreur.ERREUR_TECH_DAO);
            techErr.setLibelle("Message HibernateException : "+he.getMessage());
            log.error(techErr.formaterNagios());
            throw techErr;
        }       
    }


la ligne 197 est :
Code:
Session s = HibernateUtil.currentSession();


hibernateUtil.class est dans un jar qui est dans WEB-INF/lib de mon .war.


et dans hiebernate util le code est :

Code:
   /**
     *
     * @return
     * @throws HibernateException
     */
    public static Session currentSession() throws HibernateException {
        Session s = (Session) session.get();

        // Ouvre une nouvelle Session, si ce Thread n'en a aucune
        if (s == null) {
            s = sessionFactory.openSession();
            session.set(s);
        }

        if (!s.isOpen()){
            s.reconnect();
        }
        return s;
    }


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 8:24 am 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
En mode debug, c'est effectivement en allant sur cette ligne :
Code:
Session s = HibernateUtil.currentSession();


que mon appli plante, ce que je comprend pas c 'est pourquoi le fait de mettre "property-ref" dans mon fichier de mapping influerais sur mon accès à HibernateUtil.

Comme je débute avec hibernate, j'ai pensé que la mapping plantais et m'empechais d'ouvrir une session.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 11:28 am 
Pro
Pro

Joined: Fri Sep 02, 2005 4:21 am
Posts: 206
Location: Vienna
Sylad wrote:
...ce que je comprend pas c 'est pourquoi le fait de mettre "property-ref" dans mon fichier de mapping influerais sur mon accès à HibernateUtil.

Une explication simple serait que l'implémentation de property-ref utilise une library qui n'est sinon pas nécessaire.

Tu dis que tu a debuggé la ligne qui cause le problème. Normalement tu aurais alors dû voir quelle classe cause le problème. De la connaissance de cette classe dépend la correction du problème - tout le reste est de l'essai/erreur, qui peut durer longtemps...

Erik


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 1:05 pm 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
J' ai essayer de mettre tout les .jar que je pouvais trouver dans mon .war, ca na pas marché (je sais je suis un boeuf ^^).

Par contre j'ai mis hibernateUtil dans mon projet (et plus dans un jar qui est dans le projet), et ca semble plus prometteur j'ai un

Code:
property-ref not found: idAdr in class: fr.impots.appli.persistance.dao.hibernate.AdressePersistant


à résoudre mais je pense que ça me rapproche de la solution.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 15, 2005 1:35 pm 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
Finalement je voit toujours pas ce qui va pas, dans mon fichier PersonnePersistant j'ai :

Code:
<hibernate-mapping>
    <class
        name="fr.appli.persistance.dao.hibernate.PersonnePersistant"
        table="PERSONNE"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="idPersonne"
            column="IDPERSONNE"
            type="java.lang.String"
        >
            <generator class="assigned">
            </generator>
        </id>

       <many-to-one
            name="adr"
            class="fr.appli.persistance.dao.hibernate.AdressePersistant"
            cascade="all"
            outer-join="auto"
            update="true"
            insert="true"
            access="property"
            property-ref="idAdr"
            column="IDADR"
        />
...


et dans AdressePersistant :

Code:
<class
        name="fr.appli.persistance.dao.hibernate.AdressePersistant"
        table="ADRESSE"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="idAdr"
            column="IDADR"
            type="java.lang.String"
        >
            <generator class="assigned">
            </generator>
        </id>
...


Il devrait pouvoir faire le lien entre les 2, mais visiblement non :( :

Code:
Caused by: java.lang.RuntimeException: Problème de configuration : property-ref not found: idAdr in class: fr.appli.persistance.dao.hibernate.AdressePersistant
   at fr.appli.persistance.util.HibernateUtil.<clinit>(HibernateUtil.java:19)
   ... 126 more
Caused by: net.sf.hibernate.MappingException: property-ref not found: idAdr in class: fr.appli.persistance.dao.hibernate.AdressePersistant
   at net.sf.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:639)
   at net.sf.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:761)
   at fr.appli.persistance.util.HibernateUtil.<clinit>(HibernateUtiljava:17).


Apparement ca plante au niveau de ce code dans HibernateUtil :

Code:
    private static final SessionFactory sessionFactory;
    private static final Configuration cfg;

    static {
        try {
            // Crée la SessionFactory
            cfg = new Configuration();
            [b]sessionFactory = cfg.configure().buildSessionFactory();[/b]
        } catch (HibernateException ex) {
            throw new RuntimeException("Problème de configuration : " +
                ex.getMessage(), ex);
        }
    }


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 16, 2005 8:31 am 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
J'arrive pas a m'en sortir, alors juste opour vérifier, c'est bien

Code:
property-ref="idAdr"
que je dois utilisé, pour que quand j'insere en base une personne, il insere l'adresse avant ?

Sinon j'ai reussit a avancé un peut, il se trouve que je plante au niveau de la ligne
Code:
sessionFactory = c.buildSessionFactory();


dans mon hibernateUtil :

Code:
    public class HibernateUtil {
    private static final SessionFactory sessionFactory;
    private static final Configuration cfg;

    static {
        try {
            // Crée la SessionFactory
            cfg = new Configuration();
            Configuration c = cfg.configure();
            sessionFactory = c.buildSessionFactory();
        } catch (HibernateException ex) {
            throw new RuntimeException("Problème de configuration : " +
                ex.getMessage(), ex);
        } finally {
         " ".toString();
        }
    }

    private static final ThreadLocal session = new ThreadLocal();

    public static Configuration getConf() {
        return cfg;
    }

    /**
     *
     * @return
     * @throws HibernateException
     */
    public static Session currentSession() throws HibernateException {
        Session s = (Session) session.get();

        // Ouvre une nouvelle Session, si ce Thread n'en a aucune
        if (s == null) {
            s = sessionFactory.openSession();
            session.set(s);
        }

        /*
         * TODO à vérifier: il semble qu'il y ait un 'TimeOut' sur la session.
         * On la ré-ouvre si besoin
         */
        if (!s.isOpen()){
            s.reconnect();
        }
        return s;
    }

    /**
     *
     * @throws HibernateException
     */
    public static void closeSession() throws HibernateException {
        Session s = (Session) session.get();
        session.set(null);

        if (s != null) {
            s.close();
        }
    }
}


il me dit :

Code:
14:24:36,234 INFO  [Configuration] Configured SessionFactory: null
14:24:40,796 INFO  [Configuration] processing one-to-many association mappings
14:24:40,796 INFO  [Configuration] processing one-to-one association property references
14:24:55,031 INFO  [STDOUT] java.lang.ExceptionInInitializerError
14:24:55,046 INFO  [STDOUT]    at
...
14:24:55,078 INFO  [STDOUT]    at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:176)
14:24:55,078 INFO  [STDOUT]    at $Proxy5.deploy(Unknown Source)
14:24:55,078 INFO  [STDOUT]    at org.jboss.system.server.ServerImpl.doStart(ServerImpl.java:407)
14:24:55,078 INFO  [STDOUT]    at org.jboss.system.server.ServerImpl.start(ServerImpl.java:311)
14:24:55,078 INFO  [STDOUT]    at org.jboss.Main.boot(Main.java:145)
14:24:55,078 INFO  [STDOUT]    at org.jboss.Main$1.run(Main.java:399)
14:24:55,078 INFO  [STDOUT]    at java.lang.Thread.run(Thread.java:534)
14:24:55,078 INFO  [STDOUT] Caused by: java.lang.RuntimeException: Problème de configuration : property-ref not found: idAdr in class: fr.appli.persistance.dao.hibernate.AdressePersistant
14:24:55,078 INFO  [STDOUT]    at fr.appli.commun.util.persistance.dao.hibernate.HibernateUtil.<clinit>(HibernateUtil.java:20)
14:24:55,078 INFO  [STDOUT]    ... 126 more
14:24:55,078 INFO  [STDOUT] Caused by: net.sf.hibernate.MappingException: property-ref not found: idAdr in class: fr.appli.persistance.dao.hibernate.AdressePersistant
14:24:55,078 INFO  [STDOUT]    at net.sf.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:639)
14:24:55,078 INFO  [STDOUT]    at net.sf.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:761)
14:24:55,078 INFO  [STDOUT]    at fr.appli.commun.util.persistance.dao.hibernate.HibernateUtil.<clinit>(HibernateUtil.java:18)
14:24:55,078 INFO  [STDOUT]    ... 126 more
14:24:55,125 INFO  [STDOUT] 2005-09-16 14:24:55,125 DEBUG TransactionFacade.fermerSession - Fermeture de la session courante
14:24:55,125 ERROR [Engine] StandardContext[/fntdmas]StandardWrapper.Throwable
java.lang.NoClassDefFoundError
   at fr.appli.commun.util.persistance.transaction.TransactionFacade.fermerSession(TransactionFacade.java:200)


Top
 Profile  
 
 Post subject:
PostPosted: Fri Sep 16, 2005 12:05 pm 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
Avec le mode debug, j'ai remarqué que dans le code source d'hibernate, idAdr n'est pas dans la liste des propriétés de Adresse, mais est dans un "attribut à part pour la clé de la table.

Lors d'un parcourt de la Hashmap qui contient la liste des propriété il ne trouve donc pas idAdr dans la liste des propriétés, et plante.

Est ce que dans property-ref="nomAttribut", nomAttribut ne doit pas désigné la clé de la table fille?

Si je retire
Code:
property-ref="idAdr"

, il y a t'il une option qui me permet de forcer hibernate à modifier (créer) l’adresse avant la personne ?

Merci pour votre aide


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 17, 2005 12:15 pm 
Pro
Pro

Joined: Fri Sep 02, 2005 4:21 am
Posts: 206
Location: Vienna
J'ai expérimenté pas mal avec ton problème. Mes conclusions - à considérer d'un oeil critique:

1) property-ref est inutile.
2) Tes examples fonctionnent avec Hibernate 3.0.5. Mais Hibernate 3.0.5 génère un Select sur la table Adresse avant les insertions, pour vérifier que l'adresse n'est pas déjà dans la BD. Logique si l'on y réfléchit.
3) Si tu introduis une clé artificielle de type Long pour AdressesPersistant au lieu de la clé assignée idAdr - qui devient une property normale qui est un index unique - ça marche aussi avec Hibernate 2.1.6 (sans select). Grâce à cette clé il devient en effet possible pour Hibernate de savoir si une adresse est nouvelle (et doit être insérée) ou non. L'ordre des insertions est celui que tu attends.

J'espère que cela t'aide un petit peu pour trouver une solution acceptable dans ton environnement.

Erik


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 19, 2005 4:22 am 
Newbie

Joined: Wed Sep 14, 2005 12:25 pm
Posts: 14
Merci beaucoup,

Ma clé est assigné, mais c'est une String, je croit que je vais donc faire les insertions en 2 étapes.

Encore merci pour le temps que tu as consacré a ce topic ^^.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 13 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.