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 :
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
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...

Voici un bon bout de la classe ListeQuestionnaire :
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
	 */
}
et un exemple de relation inverse (dans membre):
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>();
merci d'avance pour toutes vos suggestions