Bonjour à tous,
J'ai parcouru de nombreux forums et tutos Hibernate français et anglais, mais je peine à trouver un cas aussi complexe que le mien...
Je dois développer une appli Java où trois classes DossierREG.java, Beneficiaire.java, DepenseBeneficiaire.java sont liées de la manière suivante :
- Un DossierREG contient un Set<Beneficiaire>.
- Un Beneficiaire contient un Set<DepenseBeneficiaire>.
De plus :
- Chacune des trois classes contient un identifiant du type NomDeLaClasseId.java : le précédent développeur de mon appli a, pour une raison que mon statut de débutante Hibernate m'empêche de comprendre, créé une classe NomDeLaClasseId pour chaque classe ou presque, et y toucher casse l'appli.
- La PK du DossierREG est composée d'un ID unique généré en faisant un select max(id)+1 sur la classe (ne vous fiez pas aux @Parameter nomtable_seq), et de l'ID de l'action.
- La PK du Beneficiaire est aussi composée d'un ID généré, combiné à l'ID du dossier et à l'ID de l'action.
- La PK de la DepenseBeneficiaire est composée de l'ID du dossier, de l'ID de l'action, de l'ID du Beneficiaire, et de l'ID du type de la DepenseBeneficiaire.
Je ne peux malheureusement pas toucher à la structure SQL car je ne suis pas la seule à m'appuyer sur cette base de données, et mon appli doit donc s'adapter à ces contraintes !
Si mon appli ne contient que des DossierREG et des Beneficiaire, tout va bien, j'enregistre en BDD sans souci, mais lorsque je rajoute un Set<DepenseBeneficiaire> à ma classe Beneficiaire, Hibernate me sort l'erreur suivante :
org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: fr.site.hibernate.classes.DepenseBeneficiaire.beneficiaire in fr.site.hibernate.classes.Beneficiaire.depenses
J'en déduis que mon mapping par beneficiaire n'aboutit pas là où je veux, et que les DepenseBeneficiaire n'arrivent pas à faire le lien avec les Beneficiaire...
Est-ce que quelqu'un de plus calé que moi pourrait me donner une piste, me dire quelles annotations corriger, ou quel mapping ajouter, s'il-vous-plaît ?
Je code sur Eclipse Galileo 3.5.1, avec le jdk.1.6.0_12, et Hibernate 3.
DossierREG.java
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 @Entity @Table(name="dossier") public class DossierREG implements Serializable { private static final long serialVersionUID = -4550370284540235670L; public static final String FIELD_ID = "idDossierREG"; public static final String FIELD_IDWEB = "idDossierWeb"; public static final String FIELD_BENEFICIAIRES = "beneficiaires"; private DossierREGId idDossierREG; private Long idDossierWeb; private Set<Beneficiaire> beneficiaires; @EmbeddedId @AttributeOverrides ({ @AttributeOverride(name="numero", column=@Column(name="id", length=45)) }) @AssociationOverrides ({ @AssociationOverride(name="action", joinColumns=@JoinColumn(name="action_id", referencedColumnName="id")) }) @GeneratedValue(generator="idDossierWebGenerator",strategy=GenerationType.TABLE) @GenericGenerator ( name="idDossierWebGenerator", strategy="fr.site.hibernate.utils.TableHiLoCompositeIdGenerator", parameters= { @Parameter(name="table", value="dossier_seq"), @Parameter(name="column", value="id"), @Parameter(name="max_lo", value="0"), @Parameter(name="primaryKeyGetter", value="getIdDossierREG"), @Parameter(name="fieldSetter", value="setNumero"), @Parameter(name="returnIncrementedValue", value="true") } ) public DossierREGId getIdDossierREG() { return idDossierREG; } public void setIdDossierREG(DossierREGId idDossierREG) { this.idDossierREG = idDossierREG; if(idDossierWeb == null) { try { idDossierWeb = Long.parseLong(idDossierREG.getNumero()); } catch(NumberFormatException e) {} } } @Transient @NotNull @Valid public String getNumero() { return idDossierREG.getNumero(); } public void setNumero(String numero) { idDossierREG.setNumero(numero); } @ManyToOne @JoinColumn(name="action_id", insertable=false, updatable=false) @NotNull @Valid public Action getAction() { return idDossierREG.getAction(); } public void setAction(Action action) { idDossierREG.setAction(action); } @Column(name="idweb", precision=10) public Long getIdDossierWeb() { return idDossierWeb; } public void setIdDossierWeb(Long idDossierWeb) { this.idDossierWeb = idDossierWeb; } @OneToMany(mappedBy="dossierREG") @Cascade({CascadeType.ALL}) @JoinColumns ({ @JoinColumn(name="dossier_id", referencedColumnName="id"), @JoinColumn(name="action_id", referencedColumnName="action_id") }) public Set<Beneficiaire> getBeneficiaires() throws Exception { return beneficiaires; } public void setBeneficiaires(Set<Beneficiaire> beneficiaires) { this.beneficiaires = beneficiaires; } public DossierREG() { idDossierREG = new DossierREGId(); } @Override public boolean equals(Object obj) { if(!(obj instanceof DossierREG)) return false; DossierREG dossier = (DossierREG)obj; return new EqualsBuilder() .append(dossier.getIdDossierREG(), getIdDossierREG()) .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() .append(getIdDossierREG()) .toHashCode(); } }
DossierREGId.java
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 @Embeddable public class DossierREGId implements Serializable { public static final String FIELD_NUMERO = "numero"; public static final String FIELD_ACTION = "action"; private static final long serialVersionUID = 594721741357431918L; private String numero; private Action action; public String getNumero() { return numero; } public void setNumero(String numero) { this.numero = numero; } public void setNumero(Long numero) { setNumero(numero.toString()); } @ManyToOne public Action getAction() { return action; } public void setAction(Action action) { this.action = action; } @Override public boolean equals(Object obj) { if(!(obj instanceof DossierREGId)) return false; DossierREGId id = (DossierREGId)obj; return new EqualsBuilder() .append(id.getNumero(), getNumero()) .append(id.getAction(), getAction()) .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() .append(getNumero()) .append(getAction()) .toHashCode(); } }
Beneficiaire.java
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 @Entity @Table(name="beneficiaire") public class Beneficiaire implements Serializable { public enum TypeBeneficiaire { ADHERENT ("A", "A"), FOURNISSEUR ("F", "F"), ORGANISME ("O", "O"), STAGIAIRE ("S", "S"); private String identifier; private String libelle; public String getIdentifier() { return identifier; } public String getLibelle() { return libelle; } private TypeBeneficiaire(String identifier, String libelle) { this.identifier = identifier; this.libelle = libelle; } public static TypeBeneficiaire value(String identifier) { TypeBeneficiaire result = null; for(TypeBeneficiaire typeBeneficiaire: values()) { if(typeBeneficiaire.getIdentifier().equals(identifier)) { result = typeBeneficiaire; break; } } return result; } } private static final long serialVersionUID = 3872180192633198521L; public static final String FIELD_IDBENEFICIAIRE = "identifier"; public static final String FIELD_DOSSIERREG = "dossierREG"; public static final String FIELD_ID = "id"; public static final String FIELD_DEPENSES = "depenses"; private BeneficiaireId identifier; private String numeroFacture; private Date dateFacture; private TypeBeneficiaire typeBeneficiaire; private Long stagiaire_Id; private Long adherent_Id; private Long fournisseur_Id; private Long organisme_Id; private int id; private Set<DepenseBeneficiaire> depenses; @EmbeddedId @AttributeOverrides ({ @AttributeOverride(name="id", column=@Column(name="id", length=10)) }) @AssociationOverrides ({ @AssociationOverride ( name="dossierREG", joinColumns= { @JoinColumn(name="dossier_id", referencedColumnName="id"), @JoinColumn(name="action_id", referencedColumnName="action_id") } ) }) public BeneficiaireId getIdentifier() { return identifier; } public void setIdentifier(BeneficiaireId identifier) { this.identifier = identifier; } @ManyToOne @JoinColumns ({ @JoinColumn(name="dossier_id", referencedColumnName="id", insertable=false, updatable=false), @JoinColumn(name="action_id", referencedColumnName="action_id", insertable=false, updatable=false) }) public DossierREG getDossierREG() { return identifier.getDossierREG(); } public void setDossierREG(DossierREG dossierREG) { identifier.setDossierREG(dossierREG); } @Column(name="id") public int getId() { return id; } public void setId(int id) { this.id = id; } @Column(name="nofact") public String getNumeroFacture() { return numeroFacture; } public void setNumeroFacture(String numeroFacture) { this.numeroFacture = numeroFacture; } @Column(name="dtfact") @Valid public Date getDateFacture() { return dateFacture; } public void setDateFacture(Date dateFacture) { this.dateFacture = dateFacture; } @Column(name="stagiaire_id") public void setStagiaire_Id(Long bId) { this.stagiaire_Id = bId; } public Long getStagiaire_Id() { return stagiaire_Id; } @Column(name="fournisseur_id") public void setFournisseur_Id(Long bId) { this.fournisseur_Id = bId; } public Long getFournisseur_Id() { return fournisseur_Id; } @Column(name="adherent_id") public void setAdherent_Id(Long bId) { this.adherent_Id = bId; } public Long getAdherent_Id() { return adherent_Id; } @Column(name="organisme_id") public void setOrganisme_Id(Long bId) { this.organisme_Id = bId; } public Long getOrganisme_Id() { return organisme_Id; } @OneToMany(mappedBy="beneficiaire") @Cascade({CascadeType.ALL}) @JoinColumns ({ @JoinColumn(name="dossier_id", referencedColumnName="dossier_id"), @JoinColumn(name="action_id", referencedColumnName="action_id") }) public Set<DepenseBeneficiaire> getDepenses() throws Exception { return depenses; } public void setDepenses(Set<DepenseBeneficiaire> depenses) { this.depenses = depenses; } public Beneficiaire() { identifier = new BeneficiaireId(); } public Beneficiaire(int idBeneficiaire, TypeBeneficiaire typeBeneficiaire, Long b_id) { this(); this.typeBeneficiaire = typeBeneficiaire; switch(this.typeBeneficiaire) { case ADHERENT: setAdherent_Id(b_id); break; case ORGANISME: setOrganisme_Id(b_id); break; case FOURNISSEUR: setFournisseur_Id(b_id); break; case STAGIAIRE: setStagiaire_Id(b_id); break; default: break; } setId(idBeneficiaire); } public Beneficiaire(DossierREG dossierREG) { this(); setDossierREG(dossierREG); } @Override public boolean equals(Object obj) { if(!(obj instanceof Beneficiaire)) return false; Beneficiaire beneficiaire = (Beneficiaire)obj; return new EqualsBuilder() .append(beneficiaire.getIdentifier(), getIdentifier()) .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() .append(getIdentifier()) .toHashCode(); } }
BeneficiaireId.java
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 @Embeddable public class BeneficiaireId implements Serializable { private static final long serialVersionUID = -4762088849677965696L; public static final String FIELD_DOSSIERREG = "dossierREG"; private DossierREG dossierREG; @ManyToOne public DossierREG getDossierREG() { return dossierREG; } public void setDossierREG(DossierREG dossierREG) { this.dossierREG = dossierREG; } @Override public boolean equals(Object obj) { if(!(obj instanceof BeneficiaireId)) return false; BeneficiaireId id = (BeneficiaireId)obj; return new EqualsBuilder() .append(id.getDossierREG(), getDossierREG()) .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() .append(getDossierREG()) .toHashCode(); } }
DepenseBeneficiaire.java
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 @Entity @Table(name="dep_beneficiaire") public class DepenseBeneficiaire implements Serializable { public enum NatureDepense { RTT ("01", "Remuneration temps travail"), RHTT ("16", "Remuneration hors temps travail"), AF ("17", "Allocation formation"), F ("03", "Formation"), R ("07", "Repas"), HR ("08", "Hebergement repas"), T ("09", "Transport"), D ("10", "Divers"), LS ("18", "Location salle"), LM ("19", "Location materiel"); private String identifier; private String libelle; public String getIdentifier() { return identifier; } public String getLibelle() { return libelle; } private NatureDepense(String identifier, String libelle) { this.identifier = identifier; this.libelle = libelle; } public static NatureDepense value(String identifier) { NatureDepense result = null; for(NatureDepense natureDepense: values()) { if(natureDepense.getIdentifier().equals(identifier)) { result = natureDepense; break; } } return result; } } private static final long serialVersionUID = -508614089121636369L; public static final String FIELD_ID = "identifier"; public static final String FIELD_DOSSIERREG = "dossierREG"; public static final String FIELD_DEPENSEID = "depense_id"; public static final String FIELD_BENEFICIAIREID = "beneficiaire_id"; public static final String FIELD_BENEFICIAIRETYPE = "beneficiaire_type"; public static final String FIELD_BENEFICIAIRE = "beneficiaire"; private DepenseBeneficiaireId identifier; private NatureDepense depense_id; private Long beneficiaire_id; private String beneficiaire_type; @EmbeddedId @AttributeOverrides ({ @AttributeOverride(name="id", column=@Column(name="id", length=10)) }) @AssociationOverrides ({ @AssociationOverride ( name="beneficiaire", joinColumns= { @JoinColumn(name="dossier_id", referencedColumnName="dossier_id"), @JoinColumn(name="action_id", referencedColumnName="action_id") } ) }) public DepenseBeneficiaireId getIdentifier() { return identifier; } public void setIdentifier(DepenseBeneficiaireId identifier) { this.identifier = identifier; } @ManyToOne @JoinColumns ({ @JoinColumn(name="dossier_id", referencedColumnName="id", insertable=false, updatable=false), @JoinColumn(name="action_id", referencedColumnName="action_id", insertable=false, updatable=false) }) public DossierREG getDossierREG() { return identifier.getDossierREG(); } public void setDossierREG(DossierREG dossierREG) { identifier.setDossierREG(dossierREG); } @Column(name="depense_id") @Type ( type="fr.site.hibernate.utils.GenericEnumUserType", parameters= { @Parameter(name="enumClassName", value="fr.site.hibernate.classes.DepenseBeneficiaire$NatureDepense"), @Parameter(name="valueOfMethod", value="value") } ) public void setDepense_id(NatureDepense depense_id) { this.depense_id = depense_id; } public NatureDepense getDepense_id() { return depense_id; } @Column(name="beneficiaire_id") public void setBeneficiaire_id(Long beneficiaire_id) { this.beneficiaire_id = beneficiaire_id; } public Long getBeneficiaire_id() { return beneficiaire_id; } @Column(name="beneficaire_type") public void setBeneficiaire_type(String beneficiaire_type) { this.beneficiaire_type = beneficiaire_type; } public String getBeneficiaire_type() { return beneficiaire_type; } public DepenseBeneficiaire() { identifier = new DepenseBeneficiaireId(); } public DepenseBeneficiaire(DossierREG dossierREG) { this(); setDossierREG(dossierREG); } @Override public boolean equals(Object obj) { if(!(obj instanceof DepenseBeneficiaire)) return false; DepenseBeneficiaire DepenseBeneficiaire = (DepenseBeneficiaire)obj; return new EqualsBuilder() .append(DepenseBeneficiaire.getIdentifier(), getIdentifier()) .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() .append(getIdentifier()) .toHashCode(); } }
DepenseBeneficiaireId.java
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 @Embeddable public class DepenseBeneficiaireId implements Serializable { private static final long serialVersionUID = 4891427738954480255L; public static final String FIELD_DOSSIERREG = "dossierREG"; public static final String FIELD_BENEFICIAIRE = "beneficiaire"; private DossierREG dossierREG; private Beneficiaire beneficiaire; @ManyToOne public DossierREG getDossierREG() { return dossierREG; } public void setDossierREG(DossierREG dossierREG) { this.dossierREG = dossierREG; } @ManyToOne public Beneficiaire getBeneficiaire() { return beneficiaire; } public void setBeneficiaire(Beneficiaire beneficiaire) { this.beneficiaire = beneficiaire; } @Override public boolean equals(Object obj) { if(!(obj instanceof DepenseBeneficiaireId)) return false; DepenseBeneficiaireId id = (DepenseBeneficiaireId)obj; return new EqualsBuilder() .append(id.getDossierREG(), getDossierREG()) .isEquals(); } @Override public int hashCode() { return new HashCodeBuilder() .append(getDossierREG()) .toHashCode(); } }
J'ai aussi posté sur les forums Hibernate : https://forum.hibernate.org/viewtopi...f=11&t=1008441 (FR) et https://forum.hibernate.org/viewtopic.php?f=1&t=1008443 (EN).
Partager