Bonjour,
Ma configuration :
EJB 3.0, JBOSS, Hibernate
j'ai besoin d'un peu d'aide sur un problème de persistence, alors voilà
j'ai 2 entity bean, un trainer et un assistant
Voici le trainer :
et voici l'assistant
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.lesson.model; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.OneToOne; /** * * */ @Entity public class Trainer extends Checker implements Serializable { private Assistant assistant; @Override public String toString() { return "org.lesson.model.Trainer[id=" + userId + "]"; } @OneToOne @JoinColumn(name="assistantId",referencedColumnName = "userId") public Assistant getAssistant() { return assistant; } public void setAssistant(Assistant assistant) { this.assistant = assistant; } }
Pour travailler sur ces entity beans j'ai définit les session beans respectifs :
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.lesson.model; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; /** * */ @Entity public class Assistant extends Checker implements Serializable { private Trainer trainer; @OneToOne(mappedBy="assistant") public Trainer getTrainer() { return trainer; } public void setTrainer(Trainer trainer) { this.trainer = trainer; } @Override public String toString() { return "org.lesson.model.Assistant[id=" + userId + "]"; } }
TrainerDao :
et AssistantDao :
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 package org.lesson.integration.dao; import java.util.List; import javax.ejb.Stateless; import javax.ejb.TransactionManagement; import javax.ejb.TransactionManagementType; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.lesson.model.Assistant; import org.lesson.model.Course; import org.lesson.model.Trainer; @Stateless public class TrainerDao implements TrainerDaoLocal { @PersistenceContext (unitName = "Lesson-ejbPU") EntityManager em; public void createOrUpdate(Trainer t) { em.merge(t); } public void remove(Trainer t) { em.remove(t); } public void addAssistant(Trainer t,Assistant a) { t.setAssistant(a); } public Trainer find(long id){ return em.find(Trainer.class,id); } public List<Trainer> findAll() { Query q = em.createQuery("SELECT t FROM Trainer t"); return q.getResultList(); } public Assistant findAssistant(Trainer t) { return t.getAssistant(); } // Add business logic below. (Right-click in editor and choose // "Insert Code > Add Business Method") }
Les 2 précédents sessions beans étant locaux , j'ai implémenté le pattern Façade pour les accèder en remote et les tester
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.lesson.integration.dao; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import org.lesson.model.Assistant; import org.lesson.model.Trainer; /** * */ @Stateless public class AssistantDao implements AssistantDaoLocal { @PersistenceContext (unitName = "Lesson-ejbPU") EntityManager em; public void createOrUpdate(Assistant a){ em.merge(a); } public void remove(Assistant a){ em.merge(a); } public Assistant find(long id){ return em.find(Assistant.class,id); } public List<Assistant> findAll() { Query q = em.createQuery("SELECT a FROM Assistant a"); return q.getResultList(); } public Trainer findTrainer(Assistant a) { return a.getTrainer(); } // Add business logic below. (Right-click in editor and choose // "Insert Code > Add Business Method") }
TrainerDaoFacade :
AssistantDaoFacade :
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 package org.lesson.facade; import java.util.List; import javax.ejb.EJB; import javax.ejb.Stateless; import org.lesson.integration.dao.TrainerDaoLocal; import org.lesson.model.Assistant; import org.lesson.model.Course; import org.lesson.model.Trainer; /** * */ @Stateless public class TrainerDaoFacade implements TrainerDaoFacadeRemote { @EJB private TrainerDaoLocal trainerDaoLocal; public void createOrUpdate(Trainer t) { trainerDaoLocal.createOrUpdate(t); } public void remove(Trainer t) { trainerDaoLocal.remove(t); } public Trainer find(long id){ return trainerDaoLocal.find(id); } public List<Trainer> findAll() { return trainerDaoLocal.findAll(); } public void addAssistant(Trainer t, Assistant a) { trainerDaoLocal.addAssistant(t, a); } public Assistant findAssistant(Trainer t) { return trainerDaoLocal.findAssistant(t); } }
et on arrive au fichier de test JUNIT :
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.lesson.facade; import java.util.List; import javax.ejb.EJB; import javax.ejb.Stateless; import org.lesson.integration.dao.AssistantDaoLocal; import org.lesson.model.Assistant; /** * */ @Stateless public class AssistantDaoFacade implements AssistantDaoFacadeRemote { // Add business logic below. (Right-click in editor and choose // "Insert Code > Add Business Method") @EJB private AssistantDaoLocal assistantDaoLocal; public void createOrUpdate(Assistant a) { assistantDaoLocal.createOrUpdate(a); } public void remove(Assistant a) { assistantDaoLocal.remove(a); } public Assistant find(long id) { return assistantDaoLocal.find(id); } public List<Assistant> findAll() { return assistantDaoLocal.findAll(); } }
Quand j'exécute le code du test, en base l'assistant est ajouté, le trainer également. Cependant le trainer n'a pas la foreign vers l'assistant (NULL), et encore pire, lorsque je fais un createOrUpdate du même trainer le second coup un nouveau trainer est créé au lieu de faire une fusion ! et l'id que j'affiche est toujours NULL également.
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 @Test public void addAssistant() { try { InitialContext ctx; ctx = new InitialContext(ht); Object ref = ctx.lookup("java:/AssistantDaoFacade/remote"); AssistantDaoFacadeRemote assistantRemote = (AssistantDaoFacadeRemote) PortableRemoteObject.narrow(ref,AssistantDaoFacadeRemote.class); ref = ctx.lookup("java:/TrainerDaoFacade/remote"); TrainerDaoFacadeRemote trainerRemote = (TrainerDaoFacadeRemote) PortableRemoteObject.narrow(ref,TrainerDaoFacadeRemote.class); Assistant a = new Assistant(); a.setName("assistant"); a.setSurname("assistant"); a.setPassword("password"); assistantRemote.createOrUpdate(a); Trainer t = new Trainer(); t.setName("trainer"); t.setSurname("trainer"); t.setPassword("password"); trainerRemote.createOrUpdate(t); System.out.println("trainer id is : "+t.getUserId()); trainerRemote.addAssistant(t, a); a.setTrainer(t); trainerRemote.createOrUpdate(t); Assistant aFound = trainerRemote.findAssistant(t); if(aFound == null){ fail("Assistant not found"); } // trainerRemote.createOrUpdate(t); } catch (NamingException ex) { Logger.getLogger(TrainerDaoFacadeTest.class.getName()).log(Level.SEVERE, null, ex); } }
autre précision trainer et assistant héritent tous deux de la classe checker qui hérite elle même de la classe user (je ne sais pas si ça peut aider)
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.lesson.model; import java.io.Serializable; import java.util.Date; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Temporal; /** * */ @Entity(name="LESSON_USER") @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public abstract class User implements Serializable { private static final long serialVersionUID = 1L; protected Long userId; protected String password; protected String name; protected String surname; @Temporal(javax.persistence.TemporalType.DATE) protected Date birthdate; @Id @GeneratedValue(strategy = GenerationType.TABLE) public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public Date getBirthdate() { return birthdate; } public void setBirthdate(Date birthdate) { this.birthdate = birthdate; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } @Override public int hashCode() { int hash = 0; hash += (userId != null ? userId.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof User)) { return false; } User other = (User) object; if ((this.userId == null && other.userId != null) || (this.userId != null && !this.userId.equals(other.userId))) { return false; } return true; } @Override public String toString() { return "org.lesson.model.User[id=" + userId + "]"; } }
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 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.lesson.model; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import javax.persistence.Entity; import javax.persistence.OneToMany; /** * */ @Entity public abstract class Checker extends User implements Serializable { }
Partager