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 :

Many to Many bidirectionnelle avec Hibernate Annotation


Sujet :

Hibernate Java

  1. #1
    Membre expérimenté

    Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 690
    Points : 1 478
    Points
    1 478
    Par défaut Many to Many bidirectionnelle avec Hibernate Annotation
    Bonjour,
    Je sais que c'est juste un instruction que je dois ajouter quelque part, mais je ne sais pas laquelle
    Je veux faire un Many to Many bidirectionnel entre deux classes. Avec le code suivant j'obtiens deux tables de jointures, comme si les associations étaient indépendantes entre elles :
    Pour la classe Produit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ...
    @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE},
    			targetEntity=com.dimedia.entities.Auteur.class)
    ...
    Pour la classe Auteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ...
    @ManyToMany (cascade={CascadeType.PERSIST, CascadeType.MERGE},
    			targetEntity=com.dimedia.entities.Produit.class)
    ...
    Que dois je ajouter pour n'utiliser qu'une seule table de jointure ???
    Merci de votre aide !

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 953
    Points : 4 379
    Points
    4 379
    Par défaut
    Citation Envoyé par ygrim Voir le message
    Que dois je ajouter pour n'utiliser qu'une seule table de jointure ???
    Merci de votre aide !
    @JoinTable(name=…

  3. #3
    Membre expérimenté

    Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 690
    Points : 1 478
    Points
    1 478
    Par défaut
    J'ai essayé ça mais la jointure n'est pas bidirectionnelle pour autant !
    Il faut toujours que j'utilise le setter de la classe produit pour que la jointure se fasse en base de données ...

  4. #4
    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
    Tu trouveras un exemple avec ce lien, un peu plus bas dans la doc:
    http://www.hibernate.org/hib_docs/an...on-collections

    D'un coté, il faut un "@JoinTable" comme cela a été dit, et de l'autre il faut un "mappedBy".

  5. #5
    Membre expérimenté

    Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 690
    Points : 1 478
    Points
    1 478
    Par défaut
    Salut,
    J'ai fait ça mais sa donne le même effet : unilatéral.
    Je pense que le mieux est que je poste mes bouts de code :
    La classe produit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    	@ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE},
    			targetEntity=com.dimedia.entities.Auteur.class)
     
    	@JoinTable (name="Auteur_Produit",
    			joinColumns={@JoinColumn(name="Produit")}, inverseJoinColumns={@JoinColumn(name="Auteur")}
    	)
    	public List<Auteur> getAuteurs() {
    		return auteurs;
    	}
    La classe auteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    @ManyToMany (cascade={CascadeType.PERSIST, CascadeType.MERGE},
    			targetEntity=com.dimedia.entities.Produit.class,mappedBy="auteurs")
     
    	public List<Produit> getProduits() {
    		return produits;
    	}
    Et ma méthode JUnit qui teste tout ça :
    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
    public void testManyToManyProduitAuteur() {
    		Auteur aut = new Auteur ();
    		aut.setNomAuteur("many to many");
     
    		Produit prod = new Produit();
    		prod.setCodeEAN("manytomany");
     
    		List<Produit> prods = new ArrayList<Produit>();
    		prods.add(prod);
     
    		List<Auteur> auts = new ArrayList<Auteur>();
    		auts.add(aut);
     
    		auteurDAO.saveAuteurs(auts);
    		produitDAO.saveProduits(prods);
     
    		prod.setAuteurs(auts);
    		produitDAO.saveProduit(prod);
     
    		Produit prod2 = new Produit();
    		prod2.setCodeEAN("manytoomany");
    		prods.add(prod2);
    		produitDAO.saveProduit(prod2);
     
    		aut.setProduits(prods);
    		auteurDAO.saveAuteur(aut);
     
    		Query q = auteurDAO.getSession().createSQLQuery("select * from auteur_produit");
    		List result = q.list();
    		// On a mappé deux produits avec un auteur, donc au min 2 entrées dans la table !
    		assertTrue(result.size() >= 2);
    	}
    Je me traine cette erreur depuis une semaine en TODO...

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 953
    Points : 4 379
    Points
    4 379
    Par défaut
    Citation Envoyé par ygrim Voir le message
    Salut,
    J'ai fait ça mais sa donne le même effet : unilatéral.

    Je me traine cette erreur depuis une semaine en TODO...
    et ajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    @JoinTable (name="Auteur_Produit",
    			joinColumns={@JoinColumn(name="Auteur")}, inverseJoinColumns={@JoinColumn(name="Produit")}
    	)
    du côté Auteur… ?

  7. #7
    Membre expérimenté

    Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 690
    Points : 1 478
    Points
    1 478
    Par défaut
    Non, je l'avais essayé et ça ne fonctionnait pas. Je l'ai rééssayé là par acquis de conscience et ça ne donne rien
    C'est drôle quand même... Est ce que ça peut avoir rapport avec le fichier de configuration Hibernate (une option que j'aurais activé mais dont je connais pas la portée ?) :
    Hibernate.cfg.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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    <hibernate-configuration>
        	<session-factory>
    	    	<!-- Database connection settings -->
    	        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    	        <property name="connection.url">jdbc:mysql://localhost/spdimedia</property>
    	        <property name="connection.username">root</property>
    	        <property name="connection.password"></property>
     
    	        <!-- JDBC connection pool (use the built-in) -->
    	        <property name="connection.pool_size">1</property>
     
    	        <!-- SQL dialect -->
    	        <property name="hibernate.dialect">org.hibernate.dialect.MySQLMyISAMDialect</property>
     
    	        <!-- Enable Hibernate's automatic session context management -->
    	        <property name="current_session_context_class">thread</property>
     
    	        <!-- Disable the second-level cache  -->
    	        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
     
    	        <!-- Echo all executed SQL to stdout -->
    	        <property name="show_sql">true</property>
     
    	        <!-- Drop and re-create the database schema on startup -->
    	        <property name="hbm2ddl.auto">create</property>
     
        		<mapping class="com.dimedia.entities.Auteur"/>
        		<mapping class="com.dimedia.entities.Collection"/>
        		<mapping class="com.dimedia.entities.DocumentRentree" />
        		<mapping class="com.dimedia.entities.Editeur" />
        		<mapping class="com.dimedia.entities.Produit" />
        		<!--<mapping class="com.dimedia.entities.Sujet" />-->
        		<!--<mapping class="com.dimedia.entities.Theme" />-->
     
        	</session-factory>
     
     
        </hibernate-configuration>

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

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 953
    Points : 4 379
    Points
    4 379
    Par défaut
    Citation Envoyé par ygrim Voir le message
    Non, je l'avais essayé et ça ne fonctionnait pas. Je l'ai rééssayé là par acquis de conscience et ça ne donne rien
    C'est drôle quand même... Est ce que ça peut avoir rapport avec le fichier de configuration Hibernate (une option que j'aurais activé mais dont je connais pas la portée ?) :
    Hibernate.cfg.xml :
    et le persistence.xml ?

  9. #9
    Membre expérimenté

    Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    690
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 690
    Points : 1 478
    Points
    1 478
    Par défaut
    J'en ai pas... Ce n'est pas nécessaire, n'est ce pas !

  10. #10
    Membre à l'essai
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2008
    Messages : 12
    Points : 11
    Points
    11
    Par défaut
    Bonjour,

    Je suis novice en EJB3 et j'ai un problème similaire sur une relation ManyToMany. Je ne sais pas si je l'ai correctement faite.

    J'ai une classe User et une Classe Client (Cli). Le but est qu'un client puisse être vu par différents utilisateur et qu'un utilisateur puisse gérer plusieurs clients.

    Mes annotations sur User :

    @ManyToMany(cascade=CascadeType.PERSIST)
    @JoinTable(name="cliuser",
    joinColumns=@JoinColumn(name="login",referencedColumnName="login"),
    inverseJoinColumns=@JoinColumn(name="icli",referencedColumnName="icli"))
    private Collection<Cli> clients;

    Mes annotations sur Client :

    @ManyToMany (cascade = CascadeType.PERSIST, mappedBy="clients")
    private Collection<User> users;

    Le but est d'obtenir une table d'association cliuser qui fasse la relation.

    Mais quand je met à jour un User j'ai une l'erreur suivante :
    [#|2008-03-26T11:11:37.562+0100|INFO|sun-appserver9.1|javax.enterprise.system.container.ejb|_ThreadID=19;_ThreadName=httpSSLWorkerThread-8080-0;|
    javax.ejb.EJBException
    at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:3869)
    at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:3769)
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:3571)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1354)
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1316)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:205)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:127)
    at $Proxy119.edit(Unknown Source)
    at net.astek.astekcontacts.UserEJB.update(UserEJB.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:406)
    at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)
    at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1417)
    at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:878)
    at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:121)
    at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)
    at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:49)
    at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)
    at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:146)
    at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:274)
    at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:377)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:290)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
    at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
    at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
    Caused by: java.lang.NullPointerException
    at oracle.toplink.essentials.internal.sessions.MergeManager.registerObjectForMergeCloneIntoWorkingCopy(MergeManager.java:670)
    at oracle.toplink.essentials.internal.sessions.MergeManager.getTargetVersionOfSourceObject(MergeManager.java:219)
    at oracle.toplink.essentials.mappings.CollectionMapping.mergeIntoObject(CollectionMapping.java:786)
    at oracle.toplink.essentials.internal.descriptors.ObjectBuilder.mergeIntoObject(ObjectBuilder.java:2152)
    at oracle.toplink.essentials.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:442)
    at oracle.toplink.essentials.internal.sessions.MergeManager.mergeChanges(MergeManager.java:264)
    at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:2723)
    at oracle.toplink.essentials.internal.ejb.cmp3.base.RepeatableWriteUnitOfWork.mergeCloneWithReferences(RepeatableWriteUnitOfWork.java:219)
    at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerImpl.mergeInternal(EntityManagerImpl.java:235)
    at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.merge(EntityManagerImpl.java:128)
    at com.sun.enterprise.util.EntityManagerWrapper.merge(EntityManagerWrapper.java:476)
    at com.jyb.astekrefs.ejb.UserBean.edit(UserBean.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1067)
    at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:176)
    at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2895)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:3986)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:197)
    ... 45 more
    |#]

    Est-ce que vous pensez que ça vient du CascadeType ? Si oui c'est quoi le problème selon vous ? Le cascading est là pour agir sur la table d'association (cliuser) ou l'autre objet associé (Cli) ?

    Merci d'avance pour votre aide.

Discussions similaires

  1. Réponses: 4
    Dernier message: 27/10/2014, 16h30
  2. [2.x] [Symfony2] Many-to-Many bidirectionnelle avec attributs
    Par Legenyes dans le forum Symfony
    Réponses: 0
    Dernier message: 03/06/2013, 14h33
  3. [Data] erreur many to one avec hibernate et spring
    Par hanen14 dans le forum Spring
    Réponses: 2
    Dernier message: 13/04/2010, 13h37
  4. Problème de séquence avec Hibernate annotation
    Par GabriHell dans le forum Hibernate
    Réponses: 1
    Dernier message: 29/07/2008, 17h52
  5. Un peu de mal a comprendre le concepte "one-to-many" et "many-to-many"
    Par chriscoolletoubibe dans le forum Hibernate
    Réponses: 4
    Dernier message: 29/03/2007, 18h50

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