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 :

cascade = {CascadeType.REMOVE} pas suffisant?


Sujet :

Hibernate Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Par défaut cascade = {CascadeType.REMOVE} pas suffisant?
    Bonjour,

    J'ai deux entités : Membre et Questionnaire qui sont en association ManyToMany avec une colonne supplémentaire. J'ai donc aussi une entité ListeQuestionnaire qui représente l'association et une classe ListeQuestionnairePk pour la clé composite.

    dans mon entité Questionnaire, j'ai donc une association @OneToMany avec ListeQuestionnaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	@OneToMany(mappedBy = "pk.questionnaire", cascade = {CascadeType.REMOVE}, fetch = FetchType.LAZY)
    	private List<ListeQuestionnaire> listeQuestionnaires = new ArrayList<ListeQuestionnaire>();
    C'est dans ma classe métier ServiceQuestionnaire que je remplis la table ListeQuestionnaire par la méthode publierQuestionnaire :
    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
    @Transactional
    public Questionnaire publierQuestionnaire(Long idQuestionnaire){
    	System.out.println("------------ publierQuestionnaire");
    	Questionnaire questionnaire = questionnaireDao.getOne(idQuestionnaire);
    	Character sexeDestinataire = questionnaire.getSexeDestinataire();
     
    	if(sexeDestinataire != null)
    	{	
    		//On recherche tous les membres concernés par ce questionnaire
    		List<Membre> membreConcernes = null;
    		switch(sexeDestinataire)
    		{
    			case 'f' :
    			{
    				membreConcernes = serviceMembre.findFemmes();
    				break;
    			}
    			case 'h' : 
    			{
    				membreConcernes = serviceMembre.findHommes();
    				break;
    			}
    			case 'b' :
    			{
    				membreConcernes = serviceMembre.findAll();
    				break;
    			}
    		}
     
    		//On enregistre les liens entre le nouveau questionnaire et les membres concernés
    		for (Membre membre : membreConcernes) {
    			ListeQuestionnaire listeQ = new ListeQuestionnaire();
    			listeQ.setARepondu(false);
    			listeQ.setMembre(membre);
    			listeQ.setQuestionnaire(questionnaire);
    			listeQ = serviceListeQuestionnaire.saveOne(listeQ);
    			questionnaire.getListeQuestionnaires().add(listeQ);
    		}
     
    		questionnaire.setPublie(true);
    		questionnaire = questionnaireDao.saveOne(questionnaire);
    	}
    	else
    	{
    		throw new RuntimeException("Le sexe des destinataires du questionnaire n'est pas défini !");
    	}
     
    	return questionnaire;
    }
    quand les lignes 40-41 sont commentées, la méthode fonctionne bien.
    Par contre, quand ces lignes sont présentes, je me retrouve avec l'erreur suivante, lancée par questionnaire = questionnaireDao.saveOne(questionnaire);:
    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
    javax.persistence.EntityNotFoundException: Unable to find fr.statlife.protoE4N.data.entites.ListeQuestionnaire with id ListeQuestionnairePk [idMembre=ben.joris, idQuestionnaire=1]
    	at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:132)
    	at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:233)
    	at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285)
    	at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
    	at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1080)
    	at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:1028)
    	at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:623)
    	at org.hibernate.type.EntityType.resolve(EntityType.java:431)
    	at org.hibernate.type.EntityType.replace(EntityType.java:291)
    	at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:507)
    	at org.hibernate.type.CollectionType.replace(CollectionType.java:574)
    	at org.hibernate.type.TypeFactory.replace(TypeFactory.java:548)
    	at org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:563)
    	at org.hibernate.event.def.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:288)
    	at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:261)
    	at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:84)
    	at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:859)
    	at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:843)
    	at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:847)
    	at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:682)
    	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:597)
    	at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
    	at $Proxy30.merge(Unknown Source)
    	at fr.statlife.protoE4N.data.dao.jpa.AbstractDaoJPAImpl.saveOne(AbstractDaoJPAImpl.java:44)
    	at fr.statlife.protoE4N.metier.ServiceQuestionnaireImpl.publierQuestionnaire(ServiceQuestionnaireImpl.java:96)
    	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:597)
    	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    	at $Proxy38.publierQuestionnaire(Unknown Source)
    	at fr.statlife.protoE4N.metier.TestServiceQuestionnaire.testPublierQuestionnaireHomme(TestServiceQuestionnaire.java:79)
    	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:597)
    	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
    	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Il me dit qu'il trouve pas une entité ListeQuestionnaire, j'en déduis qu'il cherche à enregistrer le champs List<ListeQuestionnaire> listeQuestionnaires du questionnaire.
    Pourtant, je pensais que spécifier cascade = {CascadeType.REMOVE} de l'annotation @OneToMany était suffisant pour qu'il fasse abstraction de ce champs

    Du coup je comprends pas trop où est mon erreur. Est ce que quelqu'un pourrait éclairer ma lanterne sur ce qu'il se passe ?

  2. #2
    Membre très actif
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 214
    Par défaut
    Bonjour,

    Citation Envoyé par zaboug Voir le message
    je me retrouve avec l'erreur suivante, lancée par questionnaire = questionnaireDao.saveOne(questionnaire);
    Pourquoi faire un merge du questionnaire alors qu'apriori il est déjà managé puisque récupéré via un DAO à la ligne 4 ?

  3. #3
    Membre éclairé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Par défaut
    erreur de débutant
    en fait, au départ j'en avais pas fait, mais ça me génèrait une autre erreur :
    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
    Hibernate: 
        update
            Questionnaire 
        set
            numero=?,
            publie=?,
            sexeDestinataire=?,
            titre=? 
        where
            idQuestionnaire=?
    WARN  - JDBCExceptionReporter      - SQL Error: 1205, SQLState: 41000
    ERROR - JDBCExceptionReporter      - Lock wait timeout exceeded; try restarting transaction
    ERROR - tractFlushingEventListener - Could not synchronize database state with session
    org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
    [...]
    et j'ai fini par perdre de vue cette première erreur

    au final, il suffit d'ajouter l'attribut propagation à l'annotation @Transactional de la méthode pour que ça passe bien (après avoir supprimé l'appel au merge, biensur):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @Transactional(propagation=Propagation.NEVER)
    Par contre je ne maitrise pas bien cette annotation, pourquoi elle est nécessaire ici mais pas toute les méthodes?
    Faut-il la mettre en prévention partout pour être sur ?
    J4ai du mal à mesurer son impact...

  4. #4
    Membre très actif
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 214
    Par défaut
    Ta première erreur c'était apparemment un timeout sur un lock.

    Mais là je ne suis pas sûr que ça soit vraiment ça que tu veuilles faire. Avec Propagation.NEVER tu demandes l'exécution hors transaction (et même de lever une exception si une transaction est en cours)...

  5. #5
    Membre éclairé
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Par défaut
    arf
    bon, alors ça résoud le problème sans être la solution...
    en fait, j'avais trouvé cette solution sur le forum stackoverflow quand j'avais eu la même erreur dans ma classe de tests unitaire du dao de ListeQuestionnaire.
    sur ce forum il est dit
    You can solve it by breaking main transaction into several separate transactions
    le problème était pas exactement le même, mais l'erreur si, donc j'en avais déduis que l'attribut propagation.NEVER permettait de lancer plusieurs transaction à la suite plutôt qu'une grosse transaction rassemblant le tout...

    tu as une autre idée de la source possible d'un timeout de la requête lors d'un update? parce que je sais pas du tout dans quelle direction aller chercher du coup

  6. #6
    Membre très actif
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2011
    Messages : 214
    Par défaut
    Tu n'es pas la première a avoir ce genre de soucis dernièrement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/08/2009, 03h31
  2. [Tableaux] array_unique() pas suffisant
    Par Anduriel dans le forum Langage
    Réponses: 3
    Dernier message: 25/08/2009, 12h34
  3. out of memory java heap space : 2048M pas suffisant?
    Par waflyx dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 21/12/2007, 19h58
  4. Clé étrangère et CASCADE ne fonctionne pas (MySQL 5.0)
    Par ctobini dans le forum Administration
    Réponses: 3
    Dernier message: 07/11/2007, 15h44
  5. Cascade="all" ou pas ?
    Par gazier20 dans le forum Hibernate
    Réponses: 2
    Dernier message: 16/06/2007, 15h55

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