Bonjour,
j'ai 3 entités : Membre, Questionnaire et ListeQuestionnaire.
ListeQuestionnaire correspond à l'association ManyToMany entre Membre et Questionnaire.
J'ai aussi 3 dao, un pour chaque entité.
Le problème vient du dao de ListeQuestionnaire : toutes les méthodes faisant directement appel à l'entity manager (genre persist, merge, delete, find) fonctionnent bien.
Par contre, dès que je tente une requête JPQL, ça plante au moment du getResultList() ou getSingleResult() avec l'erreur suivante :
je comprends pas pourquoi il me dit que le Membre est un objet transient alors que je l'ai bien persisté en base avant de construire l'objet listeQuestionnaire. D'ailleurs sans ça la méthode em.find() ne marcherait pas...
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 java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: fr.statlife.protoE4N.data.entites.ListeQuestionnaire.membre -> fr.statlife.protoE4N.data.entites.Membre at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1232) at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168) at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:250) at fr.statlife.protoE4N.data.dao.jpa.ListeQuestionnaireDaoImpl.findAll(ListeQuestionnaireDaoImpl.java:33) 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 $Proxy28.findAll(Unknown Source) at fr.statlife.protoE4N.data.dao.jpa.TestListeQuestionnaireDao.testFindAll(TestListeQuestionnaireDao.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) Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: fr.statlife.protoE4N.data.entites.ListeQuestionnaire.membre -> fr.statlife.protoE4N.data.entites.Membre at org.hibernate.engine.CascadingAction$9.noCascade(CascadingAction.java:387) at org.hibernate.engine.Cascade.cascade(Cascade.java:172) at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154) at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145) at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88) at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:58) at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1175) at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1251) at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102) at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:241) ... 42 more
Voici un bon bout de la classe ListeQuestionnaire :
et un exemple de relation inverse (dans membre):
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 @Entity public class ListeQuestionnaire extends DomainObject { private static final long serialVersionUID = -6692608372646294912L; //clé primaire composite @EmbeddedId private ListeQuestionnaireId id = new ListeQuestionnaireId(); /* * Pour les deux attributs suivant, on fait le lien entre l'attribut et sa colonne dans la table * via l'annotation @JoinColumn * les propriétés (insertable=false, updatable=false) spécifient que JPA ne doit pas gérer ces clés * étrangères car c'est fait directement dans par l'application via le constructeur */ @ManyToOne(optional=false) @JoinColumn(name="idMembre", insertable=false, updatable=false) private Membre membre; @ManyToOne(optional=false) @JoinColumn(name="idQuestionnaireReduit", insertable=false, updatable=false) private QuestionnaireReduit questionnaireReduit; private Boolean aRepondu; /* * Constructeurs */ public ListeQuestionnaire(){ } public ListeQuestionnaire(Membre membre, QuestionnaireReduit questionnaireReduit) { //On fixe les clés étrangères getId().setIdMembre(membre.getIdMembre()); getId().setIdQuestionnaireReduit(questionnaireReduit.getIdQuestionnaireReduit()); //Associations bidirectionnelles this.membre = membre; this.questionnaireReduit = questionnaireReduit; membre.getListeQuestionnaires().add(this); questionnaireReduit.getListeQuestionnaire().add(this); } /** * Classe définissant la clé primaire composite */ @Embeddable public static class ListeQuestionnaireId implements Serializable{ private static final long serialVersionUID = 1L; //Composantes de la clé primaire composite private String idMembre; private Long idQuestionnaireReduit; /* * Getters and Setters */ public String getIdMembre() { return idMembre; } public void setIdMembre(String idMembre) { this.idMembre = idMembre; } public Long getIdQuestionnaireReduit() { return idQuestionnaireReduit; } public void setIdQuestionnaireReduit(Long idQuestionnaireReduit) { this.idQuestionnaireReduit = idQuestionnaireReduit; } /* * (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "Id [idMembre=" + idMembre + ", idQuestionnaireReduit=" + idQuestionnaireReduit + "]"; } } /* * Getters and Setters */ }
merci d'avance pour toutes vos suggestions
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 //Relation inverse de la relation ManyToOne ListeQuestionnaire -> Membre //Cascade de suppression : la suppression d'un Membre entraine la suppression des //ListeQuestionnaire correspondant @OneToMany(mappedBy="membre", cascade={CascadeType.REMOVE}, fetch=FetchType.LAZY) private Set<ListeQuestionnaire> listeQuestionnaires = new HashSet<ListeQuestionnaire>();
Partager