Bonjour,
Je travaille sur une projet JEE avec JSF et les EJB3.
J'ai une clé composé de 3 clé étrangères, afin de gérer la clé composé j'ai utiliser l'annotation @idclass et côté JSF pour la création d'un nouveau enregistrement j'ai utiliser <selectonemenu> une liste qui me propose les valeurs disponibles dans les table en relations avec la table intermédiaire.
J'ai pas utiliser les annotation @onetomany ou autres, mon objectif est de faire entrer un enregistrement dans la table intermédiaire via 2 listes qui limite le choix pour l'utilisateur et qui récupère ce qui est déjà insérer sans utiliser les relations entre les entités.

Voilà l'entité de la table intermédiaire:
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
@Entity
@Table(name = "etud_cour")
@IdClass (EtudCourPK.class)
 
public class EtudCour implements Serializable {
 
    @Id
@Column(name = "id2")
private int id2;
 
    @Id
@Column(name = "id1")
private int id1 ;
 
@Column(name = "observation")
private String observation;
 
 
  public EtudCour() {   }
 
    public EtudCour(int id2, int id1) {
        this.id2 = id2;
        this.id1 = id1;
    }
 
public int getid2() { return id2; }
public void setid2 (int id2) { this.id2 = id2; }
public void setid1 (int id1) { this.id1 = id1; }
public int getid1() { return id1; }
 
    public String getObservation() {
        return observation;
    }
 
    public void setObservation(String observation) {
        this.observation = observation;
    }
 
    @Override
    public String toString() {
        return "entities.EtudCourPK[idpers=" + id2+ ", idcours=" + id1 + "]";
    }
 
}
Voilà l'entité de la clé primaire composée:

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
 
public class EtudCourPK implements Serializable {
 
private int id2;
private int id1 ;
 
public int getid2() { return id2; }
public void setid2 (int id2) { this.id2 = id2; }
public void setid1 (int id1) { this.id1 = id1; }
public int getid1() { return id1; }
 
    @Override
    public String toString() {
        return "entities.EtudCourPK[idpers=" + id2+ ", idcours=" + id1 + "]";
    }
}
Les 2 entité représentant les tables en relations avec EtudCour via id1 pour Cour et id2 pour Etudiant :

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
@Entity
@Table(name = "cour")
@NamedQueries({
    @NamedQuery(name = "Cour.findAll", query = "SELECT c FROM Cour c"),
    @NamedQuery(name = "Cour.findById1", query = "SELECT c FROM Cour c WHERE c.id1 = :id1"),
    @NamedQuery(name = "Cour.findByCour", query = "SELECT c FROM Cour c WHERE c.cour = :cour")})
public class Cour implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "id1")
    private Integer id1;
    @Basic(optional = false)
    @Column(name = "cour")
    private String cour;
 
    public Cour() {
    }
 
    public Cour(Integer id1) {
        this.id1 = id1;
    }
 
    public Cour(Integer id1, String cour) {
        this.id1 = id1;
        this.cour = cour;
    }
 
    public Integer getId1() {
        return id1;
    }
 
    public void setId1(Integer id1) {
        this.id1 = id1;
    }
 
    public String getCour() {
        return cour;
    }
 
    public void setCour(String cour) {
        this.cour = cour;
    }
 
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id1 != null ? id1.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 Cour)) {
            return false;
        }
        Cour other = (Cour) object;
        if ((this.id1 == null && other.id1 != null) || (this.id1 != null && !this.id1.equals(other.id1))) {
            return false;
        }
        return true;
    }
 
    @Override
    public String toString() {
        return "e.Cour[id1=" + id1 + "]";
    }
 
}
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
 
@Entity
@Table(name = "etudiant")
@NamedQueries({
    @NamedQuery(name = "Etudiant.findAll", query = "SELECT e FROM Etudiant e"),
    @NamedQuery(name = "Etudiant.findById2", query = "SELECT e FROM Etudiant e WHERE e.id2 = :id2"),
    @NamedQuery(name = "Etudiant.findByNom", query = "SELECT e FROM Etudiant e WHERE e.nom = :nom")})
public class Etudiant implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "id2")
    private Integer id2;
    @Basic(optional = false)
    @Column(name = "nom")
    private String nom;
 
    public Etudiant() {
    }
 
    public Etudiant(Integer id2) {
        this.id2 = id2;
    }
 
    public Etudiant(Integer id2, String nom) {
        this.id2 = id2;
        this.nom = nom;
    }
 
    public Integer getId2() {
        return id2;
    }
 
    public void setId2(Integer id2) {
        this.id2 = id2;
    }
 
    public String getNom() {
        return nom;
    }
 
    public void setNom(String nom) {
        this.nom = nom;
    }
 
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id2 != null ? id2.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 Etudiant)) {
            return false;
        }
        Etudiant other = (Etudiant) object;
        if ((this.id2 == null && other.id2 != null) || (this.id2 != null && !this.id2.equals(other.id2))) {
            return false;
        }
        return true;
    }
 
    @Override
    public String toString() {
        return "e.Etudiant[id2=" + id2 + "]";
    }
 
}
Concernant la page JSF qui me permet d'ajouter un nouveau enregistrement EtudCour la voilà:
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
 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
 
    <ui:composition template="/template.xhtml">
        <ui:define name="title">
            <h:outputText value="#{bundle.CreateEtudCourTitle}"></h:outputText>
        </ui:define>
        <ui:define name="body">
            <h:panelGroup id="messagePanel" layout="block">
                <h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
            </h:panelGroup>
            <h:form>
                <h:panelGrid columns="2">
 
 
                    <h:outputLabel value="#{bundle.CreateEtudCourLabel_id2}" for="id2" />
                    <h:selectOneMenu id="id2" value="#{etudCourController.selected.id2}" title="#{bundle.CreateEtudCourTitle_id2}" required="true" requiredMessage="#{bundle.CreateEtudCourRequiredMessage_id2}">
                        <f:selectItems value="#{etudiantController.itemsAvailableSelectOne}"/>
                    </h:selectOneMenu>
 
                    <h:outputLabel value="#{bundle.CreateEtudCourLabel_id1}" for="id1" />
                    <h:selectOneMenu id="id1" value="#{etudCourController.selected.id1}" title="#{bundle.CreateEtudCourTitle_id1}" required="true" requiredMessage="#{bundle.CreateEtudCourRequiredMessage_id1}">
                        <f:selectItems value="#{courController.itemsAvailableSelectOne}"/>
                    </h:selectOneMenu>
 
 
                    <h:outputLabel value="#{bundle.CreateEtudCourLabel_observation}" for="observation" />
                    <h:inputText id="observation" value="#{etudCourController.selected.observation}" title="#{bundle.CreateEtudCourTitle_observation}" />
 
                </h:panelGrid>
                <br />
                <h:commandLink action="#{etudCourController.create}" value="#{bundle.CreateEtudCourSaveLink}" />
                <br />
                <br />
                <h:commandLink action="#{etudCourController.prepareList}" value="#{bundle.CreateEtudCourShowAllLink}" immediate="true"/>
                <br />
                <br />
                <h:commandLink value="#{bundle.CreateEtudCourIndexLink}" action="/index" immediate="true" />
            </h:form>
        </ui:define>
    </ui:composition>
 
</html>
Le problème qui me casse la tête c'est que à chaque insertion je choisi id1 et id2, je tape l'observation mais l'erreur suivant s'affiche:

j_idt13:id2: Erreur de validation: Valeur not valid.
j_idt13:id1: Erreur de validation: Valeur not valid.


Il y a une erreur de validation concernant les 2 clé étrangères.

J'ai essayé de forcer la liste de sélection au lieu de la récupérer comme suit:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
 <h:outputLabel value="#{bundle.CreateEtudCourLabel_id2}" for="id2" />
 <h:selectOneMenu id="id2" value="#{etudCourController.selected.id2}" title="#{bundle.CreateEtudCourTitle_id2}" required="true" requiredMessage="#{bundle.CreateEtudCourRequiredMessage_id2}">
         <f:selectItem itemValue="1"/>
         <f:selectItem itemValue="2"/>
 </h:selectOneMenu>
 
  <h:outputLabel value="#{bundle.CreateEtudCourLabel_id1}" for="id1" />
  <h:selectOneMenu id="id1" value="#{etudCourController.selected.id1}" title="#{bundle.CreateEtudCourTitle_id1}" required="true" requiredMessage="#{bundle.CreateEtudCourRequiredMessage_id1}">
          <f:selectItem itemValue="1"/>
          <f:selectItem itemValue="2"/>
 </h:selectOneMenu>
Et ça marche, l'insertion se fait, mais mon objectif et de choisir parmi les valeur qui existent déjà dans Cour et Etudiant afin d'associer un cour à un étudiant, mais j'arrive pas à trouver la cause de l'erreur car je pense que tout est correcte.
Je demande votre aide s'il vous plait car je suis bloqué la dessus, ce problème me casse la tête
Et merci d'avance.