Bonjour à tous!
Je fais face actuellement à un problème technique lié à la persistance ou plus précisément la mise à jour d'une entité de mon système en utilisant la fonction merge de l'EntityManager.
En effet, lorsque j'effectue le merge, celui-ci génère une requête de typealors que l'objet qui lui est passé en paramètre possède un ID existant en Base de donnée.
Code : Sélectionner tout - Visualiser dans une fenêtre à part insert
Ceci me fait paniquer d'autant plus que dans la documentation que j'ai lu jusqu'ici, le merge est sensé mettre à jour l'entité en paramètre au cas où celle-ci existe déja et insérer une nouvelle ligne si et seulement si l'objet n'existe pas.
Voici les codes:
La classe de base des Utilisateurs
L'entité Utilisateur
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
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444 /** * */ package com.afrikbrain.pme.genezis.datamodel.sx.base; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.MappedSuperclass; import javax.persistence.Version; import org.hibernate.validator.Email; import org.hibernate.validator.Length; import org.hibernate.validator.Min; import org.hibernate.validator.NotEmpty; import org.hibernate.validator.NotNull; import org.hibernate.validator.Pattern; import com.afrikbrain.pme.genezis.datamodel.constants.Sex; import com.afrikbrain.pme.genezis.datamodel.parameter.internationalisation.Language; import com.afrikbrain.pme.genezis.datamodel.sx.constants.UserState; /** * Classe de base des Utilisateurs * @author Jean-Jacques * @version 1.0 */ @MappedSuperclass public class UserBase implements Serializable, Comparable<UserBase> { /** * ID Genere par Eclipse */ protected static final long serialVersionUID = 1L; /** * Duree minimale de validite de session inactive */ public static final int MIN_SESSION_INVALIDITY_MAX = 10; /** * Longueur minimale de login */ public static final int MIN_LONGIN_LENGTH = 3; /** * Nom de l'Utilisateur */ @Column(name = "LASTNAME", nullable = false) @NotEmpty(message = "userbase.lastname.empty") protected String lastName; /** * Prenom de l'Utilisateur */ @Column(name = "FIRSTNAME") protected String firstName; /** * Nom de connexion de l'utilisateur (Unique) */ @Column(name = "LOGIN", nullable = false) @NotEmpty(message = "userbase.login.notempty") @Length(min = MIN_LONGIN_LENGTH, message = "userbase.login.length.invalid.min") protected String login; /** * Mot de passe de l'utilisateur */ @Column(name = "PASSWORD", nullable = false) @NotEmpty(message = "userbase.password.notempty") protected String password; /** * Email de l'utilisateur */ @Column(name = "EMAIL", nullable = true) @Email(message = "userbase.email.invalidemail") protected String email; /** * Numero de telephone de l'utilisateur */ @Column(name = "PHONE", nullable = true) @Pattern(regex = "\\+{0,1}\\d{5,20}", message = "userbase.phone.invalidphone") protected String phone; /** * Etat de l'utilisateur (Valide ou Suspendu) */ @Enumerated(EnumType.STRING) @Column(name = "STATE", nullable = false) @NotNull(message = "userbase.state.null") protected UserState state = UserState.VALID; /** * Sexe de l'Utilisateur */ @Enumerated(EnumType.STRING) @Column(name = "SEX", nullable = false) @NotNull(message = "userbase.sex.null") protected Sex sex = Sex.MAN; /** * Duree Maximale (en minute) d'une session Inactive (30 mn) */ @Column(name = "SESSION_INACTIVITY_MAX_TIME", nullable = false) @NotNull(message = "userbase.sessionInactivityMaxTime.null") @Min(value = MIN_SESSION_INVALIDITY_MAX, message = "userbase.sessionInactivityMaxTime.minvalue") protected Integer sessionInactivityMaxTime = 30; /** * Langue de l'Utilisateur */ @Enumerated(EnumType.STRING) @Column(name = "USER_LANGUAGE", nullable = false) @NotNull(message = "userbase.language.null") protected Language language = Language.fr; /** * Version de l'enregistrement */ @Version @Column(name = "USER_VERSION") private Integer version = 0; /** * Skin de l'Utilisateur */ @Column(name = "USER_SKIN") private String skin = "e-Gold"; /** * Constructeur avec initialisation * @param lastName Nom de l'Utilisateur * @param firstName Prenom de l'Utilisateur * @param sex Sexe de l'Utilisateur * @param login Nom de connexion de l'utilisateur * @param password Mot de passe de l'utilisateur * @param email Email de l'utilisateur * @param phone Numero de telephone de l'utilisateur * @param state Etat de l'utilisateur */ public UserBase(String lastName, String firstName, Sex sex, String login, String password, String email, String phone, UserState state) { this.login = login; this.password = password; this.email = email; this.phone = phone; this.setState(state); this.setSex(sex); this.setSessionInactivityMaxTime(sessionInactivityMaxTime); if(this.login != null) this.login = this.login.trim().toUpperCase(); if(this.firstName != null) this.firstName = this.firstName.trim().toUpperCase(); if(this.lastName != null) this.lastName = this.lastName.trim().toUpperCase(); } /** * Constructeur par defaut */ public UserBase() {} /** * Methode d'obtention de la Version de l'enregistrement * @return Version de l'enregistrement */ public Integer getVersion() { return version; } /** * Methode de mise a jour de la Version de l'enregistrement * @param version Version de l'enregistrement */ public void setVersion(Integer version) { this.version = version; } /** * Methode d'obtention du Nom de l'Utilisateur * @return Nom de l'Utilisateur */ public String getLastName() { return lastName; } /** * Methode de mise a jour du Nom de l'Utilisateur * @param lastName Nom de l'Utilisateur */ public void setLastName(String lastName) { this.lastName = lastName; if(this.lastName != null) this.lastName = this.lastName.trim().toUpperCase(); } /** * Methode d'obtention du Prenom de l'Utilisateur * @return Prenom de l'Utilisateur */ public String getFirstName() { return firstName; } /** * Methode de mise a jour du Prenom de l'Utilisateur * @param firstName Prenom de l'Utilisateur */ public void setFirstName(String firstName) { this.firstName = firstName; if(this.firstName != null) this.firstName = this.firstName.trim().toUpperCase(); } /** * Methode d'obtention du login de l'utilisateur * @return Login de l'utilisateur */ public String getLogin() { return login; } /** * Methode de mise a jour du login de l'utilisateur * @param login Nouveau Login */ public void setLogin(String login) { this.login = login; if(this.login != null) this.login = this.login.trim().toUpperCase(); } /** * Methode d'obtention du mot de passe de l'utilisateur * @return Mot de passe de l'utilisateur */ public String getPassword() { return password; } /** * Methode de mise a jour du mot de passe de l'utilisateur * @param password Nouveau mot de passe */ public void setPassword(String password) { this.password = password; } /** * Methode d'obtention de l'email de l'utilisateur * @return Email de l'utilisateur */ public String getEmail() { return email; } /** * Methode de mise a jour de l'email de l'utilisateur * @param email Nouvel Email */ public void setEmail(String email) { this.email = email; } /** * Methode d'obtention du telephone de l'utilisateur * @return telephone de l'utilisateur */ public String getPhone() { return phone; } /** * Methode de mise a jour du telephone de l'utilisateur * @param phone Nouveau numero de telephone */ public void setPhone(String phone) { this.phone = phone; } /** * Methode d'obtention de l'etat de l'utilisateur * @return Etat de l'utilisateur */ public UserState getState() { return state; } /** * Methode de mise a jour de l'etat de l'utilisateur * @param state Nouvel Etat */ public void setState(UserState state) { this.state = state; // Si l'etat est null if(this.state == null) this.state = UserState.VALID; } /** * Methode permettant de savoir si l'Utilisateur est suspendu * @return Etat de suspension de l'Utilisateur */ public boolean isSuspended() { // On retourne l'etat return this.state.equals(UserState.SUSPENDED); } /** * Methode permettant de savoir si l'Utilisateur est Valide * @return Etat de Validite de l'Utilisateur */ public boolean isValid() { // On retourne l'etat return this.state.equals(UserState.VALID); } /** * Methode d'obtention du Sexe de l'Utilisateur * @return Sexe de l'Utilisateur */ public Sex getSex() { return sex; } /** * Methode de mise a jour du Sexe de l'Utilisateur * @param sex Sexe de l'Utilisateur */ public void setSex(Sex sex) { this.sex = sex; // Si le sex est null if(sex == null) this.sex = Sex.MAN; } /** * Methode d'obtention de la Duree Maximale (en minute) d'une session Inactive (30 mn) * @return Duree Maximale (en minute) d'une session Inactive (30 mn) */ public synchronized Integer getSessionInactivityMaxTime() { return sessionInactivityMaxTime; } /** * Methode de mise a jour de la Duree Maximale (en minute) d'une session Inactive (30 mn) * @param sessionInactivityMaxTime Duree Maximale (en minute) d'une session Inactive (30 mn) */ public synchronized void setSessionInactivityMaxTime(Integer sessionInactivityMaxTime) { this.sessionInactivityMaxTime = sessionInactivityMaxTime; // Si la duree est nulle if(sessionInactivityMaxTime == null) this.sessionInactivityMaxTime = 30; } /** * Methode d'obtention de la Langue de l'Utilisateur * @return Langue de l'Utilisateur */ public Language getLanguage() { return language; } /** * Methode de mise a jour de la Langue de l'Utilisateur * @param language Langue de l'Utilisateur */ public void setLanguage(Language language) { this.language = language; // Si le Langage est null if(language == null) this.language = Language.fr; } /** * Methode d'obtention du Skin de l'Utilisateur * @return Skin de l'Utilisateur */ public String getSkin() { return skin; } /** * Methode de mise a jour du Skin de l'Utilisateur * @param skin Skin de l'Utilisateur */ public void setSkin(String skin) { this.skin = skin; // Si le skin est null if(this.skin == null || this.skin.trim().length() == 0) this.skin = "Classic"; } @Override public boolean equals(Object obj) { // Si le parametre est null : false if(obj == null) return false; // Si le parametre n'est pas de la classe : false if(!(obj instanceof UserBase)) return false; // On caste UserBase user = (UserBase) obj; // Si le login du parametre est null if(user.login == null || user.login.trim().length() == 0) return false; // Si le login en cours est null if(login == null || login.trim().length() == 0) return false; // On retourne la comparaison des login return this.login.equalsIgnoreCase(user.login); } /* * (non-Javadoc) * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(UserBase user) { // Si le parametre est null : 1 if(user == null) return 1; // Si l'utilisateur n'a pas de nom de connexion : 1 if(user.getLogin() == null || user.getLogin().trim().length() == 0) return 1; // Si l'objet en cours n'a pas de nom de connexion : -1 if(this.getLogin() == null || this.getLogin().trim().length() == 0) return -1; // On retourne le resultat return this.getLogin().compareTo(user.getLogin()); } }
Le code d'enregistrement
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
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 /** * */ package com.afrikbrain.pme.genezis.datamodel.sx; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import org.hibernate.annotations.MapKeyManyToMany; import com.afrikbrain.pme.genezis.datamodel.constants.Sex; import com.afrikbrain.pme.genezis.datamodel.parameter.enterprisenetwork.Node; import com.afrikbrain.pme.genezis.datamodel.sx.base.UserBase; import com.afrikbrain.pme.genezis.datamodel.sx.constants.UserState; /** * Classe representant un utilisateur de la plateforme * @author Jean-Jacques * @version 1.0 */ @Entity(name = "SXUser") @Table(name = "SX_USER") @SequenceGenerator(name="Seq_SXUser", sequenceName="SEQ_SX_USER", allocationSize = 1, initialValue = 1) public class SXUser extends UserBase implements Serializable { /** * ID Genere par eclipse */ private static final long serialVersionUID = 1L; /** * Identifiant du role */ @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "Seq_SXUser") @Column(name = "ID") protected Long id; /** * Map des Roles de l'Utilisateur par neoud d'affectation */ @ManyToMany(fetch = FetchType.EAGER) @MapKeyManyToMany( joinColumns = { @JoinColumn(name = "NODE_ID") } ) @JoinTable( name = "SX_USER_GROUP", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "GROUP_ID", nullable = false) } ) private Map<Node, SXGroupsSet> groupsPerNode = new HashMap<Node, SXGroupsSet>(); /** * Constructeur par defaut */ public SXUser() {} /** * Constructeur avec initialisation * @param lastName Nom de l'Utilisateur * @param firstName Prenom de l'Utilisateur * @param sex Sexe de l'Utilisateur * @param login Nom de connexion de l'utilisateur * @param password Mot de passe de l'utilisateur * @param email Email de l'utilisateur * @param phone Numero de telephone de l'utilisateur * @param state Etat de l'utilisateur */ public SXUser(String lastName, String firstName, Sex sex, String login, String password, String email, String phone, UserState state) { // Appel Parent super(lastName, firstName, sex, login, password, email, phone, state); } /** * Methode d'obtention du code de l'utilisateur * @return ID de l'utilisateur */ public Long getId() { return id; } /** * Methode de mise a jour du code de l'utilisateur * @param id Nouvel Identifiant */ public void setId(Long id) { this.id = id; } /** * Methode d'obtention de l'Ensemble des noeuds de l'Utilisateur * @return Ensemble des noeuds de l'Utilisateur */ public Set<Node> getNodes() { return groupsPerNode.keySet(); } /** * Methode d'obtention de la Map des Groupes de l'Utilisateur par neoud d'affectation * @return Map des Groupes de l'Utilisateur par neoud d'affectation */ public Map<Node, SXGroupsSet> getGroupsPerNode() { return groupsPerNode; } /** * Methode de mise a jour de la Map des Groupes de l'Utilisateur par neoud d'affectation * @param rolesPerNode Map des Roles de l'Utilisateur par neoud d'affectation */ public void setGroupsPerNode(Map<Node, SXGroupsSet> groupsPerNode) { this.groupsPerNode = groupsPerNode; // Si la MAP est vide if(this.groupsPerNode == null) this.groupsPerNode = new HashMap<Node, SXGroupsSet>(); } /** * Methode d'ajout d'un ensemble de groupe * @param node Noeud * @param groupsSet Ensemble de Noeud */ public void putGroupSet(Node node, SXGroupsSet groupsSet) { // Si le Noeud est null if(node == null) return; // Si la Map est nulle if(groupsPerNode == null) groupsPerNode = new HashMap<Node, SXGroupsSet>(); // Ajout if(groupsSet != null) this.groupsPerNode.put(node, groupsSet); else this.groupsPerNode.put(node, new SXGroupsSet()); } /** * Methode d'obtention du Groupset d'un Noeud * @param node Noeud * @return GroupSet */ public SXGroupsSet getGroupSet(Node node) { // Si le Noeud est null if(node == null) return null; // Si le noeud n'a pas de code if(node.getCode() == null) return null; // Si la MAP est Nulle if(groupsPerNode == null || groupsPerNode.size() == 0) return null; // Parcours for (Entry<Node, SXGroupsSet> entry : groupsPerNode.entrySet()) { // On recupere le Noeud Node key = entry.getKey(); // Si le code est le même if(key.getCode().equals(node.getCode())) return entry.getValue(); } // On retourne null return null; } /** * Methode d'obtention de l'etat d'affectation d'un utilisateur a un noeud * @param node Noeud d'affectation * @return Etat d'affectation a ce noeud */ public boolean isAffectedToNode(Node node) { // Si le Noeud est null if(node == null) return false; // Si le noeud n'a pas de code if(node.getCode() == null) return false; // Si la MAP est Nulle if(groupsPerNode == null || groupsPerNode.size() == 0) return false; // Parcours for (Entry<Node, SXGroupsSet> entry : groupsPerNode.entrySet()) { // On recupere le Noeud Node key = entry.getKey(); // Si le code est le même if(key.getCode().equals(node.getCode())) return true; } // On retourne null return false; } }
Je comprends pas pourquoi il génère une requete d'insertion
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 @Override public SXUser updateNodeUser(SXUser user) { System.out.println("ID: " + user.getId()); // On retourne l'Utilisateur enregistre return entityManager.merge(user); }
Partager