update ne marchant pas avec @OneToMany
Bonjour.
Je développe actuellement la partie persistance d'une application en JPA.
Les entités à persister sont des sondages, les questions associées à ce sondage, et les réponses associées à ces questions.
Un sondage comprend donc différents attributs ainsi qu'une collection de questions.
La création d'un sondage, qui se fait séparément de la création des questions du sondage, marche niquel. l'entité est mise en base sans problème.
J'ai la possibilité de modifier un sondage sans ajouter de question. Ceci marche sans problème également.
Lorsque j'ajoute pour la première fois une question au sondage, l'update se fait sans problème également.
En fait c'est à partir du moment où je modifie un sondage après avoir enregistré une question que ça ne marche plus.
Au niveau de la config, le serveur d'application est celui de Websphère en version 6.1
J'utilise MySQL dans l'une de ses dernières versions.
Le provider est hibernate (ligne <provider>org.hibernate.ejb.HibernatePersistence</provider> dans le persistence.xml)
L'exception lors de l'update d'un sondage est la suivante:
Code:
1 2
|
[06/07/09 09:34:25:633 CEST] 0000001c SystemErr R javax.persistence.PersistenceException: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.persistence.entities.QuestionEntity#1] |
Mon entité de sondage est construite de la manière suivante :
Code:
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
package com.persistence.entities;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import javax.persistence.*;
@Entity
@Table(name="poll_table")
public class PollEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = -8004407235103759568L;
private int identifier;
/**
*
*/
private boolean avisValidation;
/**
* l'intitulé du sondage
*/
private String intitule;
/**
*
*/
private Date dateDeb;
/**
*
*/
private Date dateFin;
/**
* la liste des questions du sondage
*/
private Collection<QuestionEntity> questions;
/**
* Constructeur obligatoire pour les entités.
*/
public PollEntity() {questions = new ArrayList<QuestionEntity>(); System.out.println("constructor de PollEntity");}
/**
* @return avisValidation
*/
public boolean isAvisValidation() {
return avisValidation;
}
/**
* @param avisValidation avisValidation à définir
*/
public void setAvisValidation(boolean avisValidation) {
this.avisValidation = avisValidation;
}
/**
* @return dateDeb
*/
public Date getDateDeb() {
return dateDeb;
}
/**
* @param dateDeb dateDeb à définir
*/
public void setDateDeb(Date dateDeb) {
this.dateDeb = dateDeb;
}
/**
* @return dateFin
*/
public Date getDateFin() {
return dateFin;
}
/**
* @param dateFin dateFin à définir
*/
public void setDateFin(Date dateFin) {
this.dateFin = dateFin;
}
/**
* @return identifier
*/
@Id
public int getIdentifier() {
return identifier;
}
/**
* @param identifier identifier à définir
*/
public void setIdentifier(int identifier) {
this.identifier = identifier;
}
/**
* @return intitule
*/
public String getIntitule() {
return intitule;
}
/**
* @param intitule intitule à définir
*/
public void setIntitule(String intitule) {
this.intitule = intitule;
}
/**
* @return questions
*/
@OneToMany(cascade=CascadeType.ALL, mappedBy="pollId")
public Collection<QuestionEntity> getQuestions() {
return questions;
}
/**
* @param questions questions à définir
*/
public void setQuestions(Collection<QuestionEntity> questions) {
this.questions = questions;
}
} |
Mon entité de question est construite de la manière suivante :
Code:
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
package com.persistence.entities;
import java.util.Collection;
import javax.persistence.*;
@Entity
@Table(name="question_table")
public class QuestionEntity {
private int pollId;
private int questionIdentifier;
private String intitule;
private String type;
private int cardMin;
private int cardMax;
private boolean ordonne;
private int rang;
private Collection<ResponseEntity> reponses;
/**
* @return reponses
*/
@OneToMany(cascade=CascadeType.ALL, mappedBy="questionId")
public Collection<ResponseEntity> getReponses() {
return reponses;
}
/**
* @param reponses reponses à définir
*/
public void setReponses(Collection<ResponseEntity> reponses) {
this.reponses = reponses;
}
/**
*
*/
public QuestionEntity() {}
/**
* @return cardMax
*/
public int getCardMax() {
return cardMax;
}
/**
* @param cardMax cardMax à définir
*/
public void setCardMax(int cardMax) {
this.cardMax = cardMax;
}
/**
* @return cardMin
*/
public int getCardMin() {
return cardMin;
}
/**
* @param cardMin cardMin à définir
*/
public void setCardMin(int cardMin) {
this.cardMin = cardMin;
}
/**
* @return intitule
*/
public String getIntitule() {
return intitule;
}
/**
* @param intitule intitule à définir
*/
public void setIntitule(String intitule) {
this.intitule = intitule;
}
/**
* @return ordonne
*/
public boolean isOrdonne() {
return ordonne;
}
/**
* @param ordonne ordonne à définir
*/
public void setOrdonne(boolean ordonne) {
this.ordonne = ordonne;
}
/**
* @return questionIdentifier
*/
@Id
public int getQuestionIdentifier() {
return questionIdentifier;
}
/**
* @param questionIdentifier questionIdentifier à définir
*/
public void setQuestionIdentifier(int questionIdentifier) {
this.questionIdentifier = questionIdentifier;
}
/**
* @return rang
*/
public int getRang() {
return rang;
}
/**
* @param rang rang à définir
*/
public void setRang(int rang) {
this.rang = rang;
}
/**
* @return type
*/
public String getType() {
return type;
}
/**
* @param type type à définir
*/
public void setType(String type) {
this.type = type;
}
/**
* @return pollId
*/
public int getPollId() {
return pollId;
}
/**
* @param pollId pollId à définir
*/
public void setPollId(int pollId) {
this.pollId = pollId;
}
} |
Mon entité de réponse est faite de la manière suivante :
Code:
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
|
package com.persistence.entities;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="response_table")
public class ResponseEntity {
private int questionId;
private String value;
private int rang;
private int identifier;
/**
*
*/
public ResponseEntity() {}
/**
* @return identifier
*/
@Id
public int getIdentifier() {
return identifier;
}
/**
* @param identifier identifier à définir
*/
public void setIdentifier(int identifier) {
this.identifier = identifier;
}
/**
* @return rang
*/
public int getRang() {
return rang;
}
/**
* @param rang rang à définir
*/
public void setRang(int rang) {
this.rang = rang;
}
/**
* @return value
*/
public String getValue() {
return value;
}
/**
* @param value value à définir
*/
public void setValue(String value) {
this.value = value;
}
/**
* @return questionId
*/
public int getQuestionId() {
return questionId;
}
/**
* @param questionId questionId à définir
*/
public void setQuestionId(int questionId) {
this.questionId = questionId;
}
} |
La mise à jour d'un sondage se fait de la manière suivante (la classe Sondage représente un sondage dans l'application. le PollEntity est modifié à partir de l'objet de type Sondage associé):
Code:
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
|
public static void updatePoll(Sondage sond) {
System.out.println("dans updatePoll");
EntityManager em = getEntityManager();
em.getTransaction().begin();
System.out.println("transaction entammée");
PollEntity poll = em.find(PollEntity.class, sond.getIdentifier());
System.out.println("nom du sondage trouvé : "+poll.getIntitule());
System.out.println("sondage récupéré");
poll.setAvisValidation(sond.isAvisValidation());
poll.setDateDeb(sond.getDateDeb());
poll.setDateFin(sond.getDateFin());
poll.setIdentifier(sond.getIdentifier());
poll.setIntitule(sond.getIntitule());
poll.getQuestions().clear();
System.out.println("avant flush");
em.flush();
System.out.println("attributs sondage récupérés");
int i = 1;
for (Question q : sond.getQuestions().values()) {
System.out.println("enregistrement de la question "+i);
i++;
QuestionEntity qe = new QuestionEntity();
System.out.println("questionEntity créé");
qe.setPollId(poll.getIdentifier());
qe.setIntitule(q.getIntitule());
qe.setCardMax(q.getCardMax());
qe.setCardMin(q.getCardMin());
qe.setOrdonne(q.isOrdonne());
qe.setQuestionIdentifier(q.getQuestionIdentifier());
qe.setRang(q.getRang());
System.out.println("attributs question récupérés");
Collection<ResponseEntity> cre = new ArrayList<ResponseEntity>();
System.out.println("collection des réponses pour la question créée");
int j = 1;
for (Reponse r : q.getReponses()) {
System.out.println("récupération de la question "+j);
j++;
ResponseEntity re = new ResponseEntity();
System.out.println("réponseEntity créé");
re.setQuestionId(qe.getQuestionIdentifier());
re.setIdentifier(r.getIdentifier());
re.setRang(r.getRang());
re.setValue(r.getValue());
System.out.println("récupération des attributs");
cre.add(re);
System.out.println("réponse ajoutée à la collection");
}
if (j==1)
System.out.println("il n'y avait pas de réponse à la question");
qe.setReponses(cre);
System.out.println("collection de réponses insérée");
System.out.println("taille de la map de questions : "+poll.getQuestions().size());
System.out.println("questions effacées");
poll.getQuestions().add(qe);
System.out.println("question insérée dans le sondage : "+poll.getQuestions().size());
}
if (i == 1)
System.out.println("il n'y avait pas de question au sondage");
System.out.println("avant commit");
try {
em.flush();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("flush effectué");
em.getTransaction().commit();
System.out.println("commit effectué");
} |
Quelqu'un aurait-il déjà eu ce problème oubien quelqu'un voit-il une erreur dans mon code? :x
Merci d'avance!