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 :

Problème avec une relation ManytoMany


Sujet :

Hibernate Java

  1. #1
    Futur Membre du Club
    Inscrit en
    Août 2005
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 6
    Points : 7
    Points
    7
    Par défaut Problème avec une relation ManytoMany
    Bonjour,

    J'ai un problème pour faire fonctionner correctement une relation manytomany.

    J'utilise Spring en version 4.0.6.RELEASE et Hibernate en version 4.3.5.Final.


    Voici le code que je lance :

    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
     
    @SpringApplicationConfiguration(classes = DomainAndPersistenceConfigTest.class)
    @RunWith(SpringJUnit4ClassRunner.class)
    public class BookServiceImplTest {
     
    	@Autowired
    	private BookService bookService;
     
            @Test
    	public void Test2() {
    	Auteur auteur = new Auteur("Nom1", "Prenom1");
     
    	bookService.addBook("Titre1", "ssTitre1", auteur);
    	bookService.addBook("Titre2", "ssTitre2", auteur);
            }
    }
    J'ai ce message d'erreur au niveau de la deuxième ligne addbook.

    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
     
    javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: mediatheque.entities.Auteur
    	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
    	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
    	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
    	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1187)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:606)
    	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
    	at com.sun.proxy.$Proxy41.persist(Unknown Source)
    	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:389)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:606)
    	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:405)
    	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:390)
    	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:344)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodIntercceptor.invoke(CrudMethodMetadataPostProcessor.java:111)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    	at com.sun.proxy.$Proxy48.save(Unknown Source)
    	at mediatheque.metier.BookServiceImpl.addBook(BookServiceImpl.java:52)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:606)
    	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    	at com.sun.proxy.$Proxy49.addBook(Unknown Source)
    	at mediatheque.metier.BookServiceImplTest.Test2(BookServiceImplTest.java:65)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    	at java.lang.reflect.Method.invoke(Method.java:606)
    	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
    Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: mediatheque.entities.Auteur
    	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
    	at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:801)
    	at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:794)
    	at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97)
    	at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
    	at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
    	at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    	at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:379)
    	at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:319)
    	at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:296)
    	at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
    	at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
    	at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:460)
    	at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:294)
    	at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
    	at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
    	at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84)
    	at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206)
    	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149)
    	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
    	at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
    	at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
    	at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
    	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
    	... 70 more
    Par contre cela fonctionne correctement, lorsque je fait :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Auteur auteur = new Auteur("Nom1", "Prenom1");
     
    bookService.addBook("Titre1", "ssTitre1", auteur);
    bookService.addBook("Titre2", "ssTitre2");
     
    bookService.addAuteurBook(2, auteur);
    Extrait de Book.java
    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
     
     
    @Entity
    public class Book {
     
    	private static final long serialVersionUID = 1L;
     
    	@Id
    	@GeneratedValue(strategy = GenerationType.IDENTITY)
    	protected Long id;
     
    	@Version
    	protected Long version = (long) 1;
     
    	@Column(length = 25)
    	private String title;
     
    	@Column(length = 50, name = "SSTITLE")
    	private String ssTitle;
     
    	@ManyToMany(fetch = FetchType.EAGER, cascade={CascadeType.PERSIST, CascadeType.MERGE} )
    	@JoinTable(name = "AuteurBook", joinColumns = @JoinColumn(name = "ID_BOOK"), inverseJoinColumns = @JoinColumn(name = "ID_AUTEUR"))
    	private Collection<Auteur> auteurs = new ArrayList<Auteur>();
     
            public Book() {
    	}
     
    	public Book(String titre, String ssTitre) {
    		this.title = titre;
    		this.ssTitle = ssTitre;
    	}
     
    	public Book(String titre, String ssTitre, final Auteur auteur) {
    		this.title = titre;
    		this.ssTitle = ssTitre;
    		this.auteurs.add(auteur);
    	}
     
            // Getter + setter
    Extrait de Auteur.java
    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
     
    @Entity
    public class Auteur {
     
    	private static final long serialVersionUID = 1L;
     
     
            @Id
    	@GeneratedValue(strategy = GenerationType.IDENTITY)
    	protected Long id;
     
    	@Version
    	protected Long version = (long) 1;
     
    	@Column(length = 15)
    	private String nom;
     
    	@Column(length = 15)
    	private String prenom;
     
    	@ManyToMany(fetch = FetchType.EAGER, mappedBy = "auteurs", cascade = {CascadeType.MERGE })
    	private Collection<Book> books = new ArrayList<Book>();
     
    	public Auteur() {
    	}
     
    	public Auteur(String nom, String prenom) {
    		this.nom = nom;
    		this.prenom = prenom;
    	}
     
    	public Auteur(Auteur auteur) {
    		this.nom = auteur.nom;
    		this.prenom = auteur.prenom;
    	}
     
            // Getter + setter

    Extrait de BookServiceImpl.java
    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
     
    @Service
    public class BookServiceImpl implements BookService {
     
    	@Resource
    	private BookRepository bookRepository;
     
    	@Transactional
    	public Book addBook(String titre, String ssTitre, Auteur auteur) {
    		Book book = new Book(titre, ssTitre);
    		book.getAuteurs().add(auteur);
     
    		return bookRepository.save(book);
    	}
     
    	@Transactional
    	public void addAuteurBook(Long id, Auteur auteur) {
    		Book book = bookRepository.findOne(id);
    		book.getAuteurs().add(auteur);
    		bookRepository.save(book);
    	}

    Extrait de BookRepository.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public interface BookRepository extends CrudRepository<Book, Long> {
    }
    Extrait DomainAndPersistenceConfigTest.java
    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
     
    @EnableTransactionManagement
    @EnableJpaRepositories(basePackages = { "mediatheque.repositories" })
    @Configuration
    @ComponentScan(basePackages = { "mediatheque.service" })
    public class DomainAndPersistenceConfigTest {
     
    	// la source de données H2
    	@Bean
    	public DataSource dataSource() {
    		EmbeddedDatabaseBuilder dataSource = new EmbeddedDatabaseBuilder();
     
    		return dataSource.setType(EmbeddedDatabaseType.H2).build();
    	}
     
    	// le provider JPA
    	@Bean
    	public JpaVendorAdapter jpaVendorAdapter() {
    		HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
    		hibernateJpaVendorAdapter.setShowSql(true);
    		hibernateJpaVendorAdapter.setGenerateDdl(true);
    		hibernateJpaVendorAdapter.setDatabase(Database.H2);
    		return hibernateJpaVendorAdapter;
    	}
     
    	@Bean
    	public EntityManagerFactory entityManagerFactory(
    			JpaVendorAdapter jpaVendorAdapter, DataSource dataSource) {
    		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    		factory.setJpaVendorAdapter(jpaVendorAdapter);
    		factory.setPackagesToScan("mediatheque.entities");
    		factory.setDataSource(dataSource);
    		factory.afterPropertiesSet();
    		return factory.getObject();
    	}
     
    	// Transaction manager
    	@Bean
    	public PlatformTransactionManager transactionManager(
    			EntityManagerFactory entityManagerFactory) {
    		JpaTransactionManager txManager = new JpaTransactionManager();
    		txManager.setEntityManagerFactory(entityManagerFactory);
    		return txManager;
    	}

    Pourquoi je ne peux pas initialiser un objet Book avec un objet Auteur déjà existant mais que je peux ajouter ce même objet Auteur à un objet Book déjà crée ?

  2. #2
    Membre expérimenté Avatar de nchal
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    512
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2012
    Messages : 512
    Points : 1 656
    Points
    1 656
    Par défaut
    Salut

    Je suis très loin d'être un expert, mais en cherchant ton erreur sur Google, je suis tombé sur des articles expliquant que c'est le bidirectionnel qui fout la merde. Donc moi j'essaierais de jouer avec les propriétés comme fetchtype ou cascade
    (genre change de cascade.merge à cascade.all)
    Si la réponse vous convient, un petit ça encourage.
    Avant tout nouveau post, pensez à : la FAQ, Google et la fonction Recherche
    Si vous devez poster, pensez à: Ecrire en français, la balise [CODE] (#) et surtout

  3. #3
    Membre chevronné Avatar de jeffray03
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2008
    Messages
    1 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 501
    Points : 2 120
    Points
    2 120
    Par défaut
    Salut,
    ou as-tu essayé de faire simplement:

    dans Book.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            @ManyToMany
    	@JoinTable(name = "AuteurBook", joinColumns = @JoinColumn(name = "ID_BOOK"), inverseJoinColumns = @JoinColumn(name = "ID_AUTEUR"))
    	private Collection<Auteur> auteurs = new ArrayList<Auteur>();
    et Auteur.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      @ManyToMany(mappedBy = "auteurs")
      private Collection<Book> books = new ArrayList<Book>();
    eric

Discussions similaires

  1. [2.x] [Doctrine 2] Problème d'insertion avec une relation manytomany
    Par Khalezis dans le forum Symfony
    Réponses: 0
    Dernier message: 14/11/2013, 12h56
  2. [2.x] Problème d'insertion avec une relation ManyToMany
    Par touffifou dans le forum Symfony
    Réponses: 0
    Dernier message: 15/05/2013, 17h39
  3. Réponses: 2
    Dernier message: 11/02/2013, 13h22
  4. Problème pour requeter avec une relation manyToMany
    Par fab76000 dans le forum Hibernate
    Réponses: 0
    Dernier message: 26/04/2011, 17h32
  5. Problème avec une relation maître détail
    Par nb-wissam dans le forum Forms
    Réponses: 2
    Dernier message: 15/06/2010, 11h03

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