Précédent   Forum des professionnels en informatique > Java > Général Java > Persistance > JPA
JPA Forum d'entraide sur l'API de persistance JPA (Java Persistence API)
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 30/12/2011, 15h47   #1
Candidat au titre de Membre du Club
 
Homme
Inscription : septembre 2009
Messages : 51
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 21
Localisation : Belgique

Informations forums :
Inscription : septembre 2009
Messages : 51
Points : 14
Points : 14
Par défaut Problèmes de ConstraintViolationException

Bonjour.

Je travaille actuellement sur un projet d'e-commerce et je rencontre une difficulté que je n'arrive pas à résoudre.

Cela se produit lorsque le client a rempli son panier et décide donc de se rendre sur la page de commande pour y rentrer ses informations personnelles. Il est invité à rentrer son nom, prénom, email, téléphone, adresse et numéro de carte de crédit.

Lorsque je veux persister mon entité client (qui contient ces informations et qui est mappée à ma BDD), j'obtiens une ConstraintViolationException (j'ai pu voir ça grâce au débuggage).

- La table client dans ma BDD :
Code :
1
2
3
4
5
6
7
id     int(10) UNSIGNED Non-null AUTO_INCREMENT     
nom     varchar(30) latin1_swedish_ci Non-null             
prenom     varchar(20) latin1_swedish_ci Non-null    
email     varchar(45) latin1_swedish_ci Non-null            
tel     varchar(30) latin1_swedish_ci Non-null             
addresse     varchar(45) latin1_swedish_ci Non-null
no_carte     varchar(20) latin1_swedish_ci Non-null
- Mon entité Client :
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package entites;
 
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
 
@Entity
@Table(name = "client")
@NamedQueries({
    @NamedQuery(name = "Client.findAll", query = "SELECT c FROM Client c"),
    @NamedQuery(name = "Client.findById", query = "SELECT c FROM Client c WHERE c.id = :id"),
    @NamedQuery(name = "Client.findByNom", query = "SELECT c FROM Client c WHERE c.nom = :nom"),
    @NamedQuery(name = "Client.findByPrenom", query = "SELECT c FROM Client c WHERE c.prenom = :prenom"),
    @NamedQuery(name = "Client.findByEmail", query = "SELECT c FROM Client c WHERE c.email = :email"),
    @NamedQuery(name = "Client.findByTel", query = "SELECT c FROM Client c WHERE c.tel = :tel"),
    @NamedQuery(name = "Client.findByAddresse", query = "SELECT c FROM Client c WHERE c.addresse = :addresse"),
    @NamedQuery(name = "Client.findByNoCarte", query = "SELECT c FROM Client c WHERE c.noCarte = :noCarte")})
public class Client implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @NotNull
    @Column(name = "id")
    private Integer id;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 30)
    @Column(name = "nom")
    private String nom;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 20)
    @Column(name = "prenom")
    private String prenom;
    // @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 45)
    @Column(name = "email")
    private String email;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 30)
    @Column(name = "tel")
    private String tel;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 45)
    @Column(name = "addresse")
    private String addresse;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 20)
    @Column(name = "no_carte")
    private String noCarte;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "idClient")
    private Collection<CommandeClient> commandeClientCollection;
 
    public Client() {
    }
 
    public Client(Integer id) {
        this.id = id;
    }
 
    public Client(Integer id, String nom, String prenom, String email, String tel, String addresse, String noCarte) {
        this.id = id;
        this.nom = nom;
        this.prenom = prenom;
        this.email = email;
        this.tel = tel;
        this.addresse = addresse;
        this.noCarte = noCarte;
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getNom() {
        return nom;
    }
 
    public void setNom(String nom) {
        this.nom = nom;
    }
 
    public String getPrenom() {
        return prenom;
    }
 
    public void setPrenom(String prenom) {
        this.prenom = prenom;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public String getTel() {
        return tel;
    }
 
    public void setTel(String tel) {
        this.tel = tel;
    }
 
    public String getAddresse() {
        return addresse;
    }
 
    public void setAddresse(String addresse) {
        this.addresse = addresse;
    }
 
    public String getNoCarte() {
        return noCarte;
    }
 
    public void setNoCarte(String noCarte) {
        this.noCarte = noCarte;
    }
 
    public Collection<CommandeClient> getCommandeClientCollection() {
        return commandeClientCollection;
    }
 
    public void setCommandeClientCollection(Collection<CommandeClient> commandeClientCollection) {
        this.commandeClientCollection = commandeClientCollection;
    }
 
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.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 Client)) {
            return false;
        }
        Client other = (Client) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }
 
    @Override
    public String toString() {
        return "entites.Client[ id=" + id + " ]";
    }    
}
- Mon ejb GestionCommande :
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
package ejb;
 
import entites.Client;
import entites.CommandeClient;
import entites.Produit;
import entites.ProduitCommande;
import entites.ProduitCommandePK;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.SessionContext;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import pannier.Pannier;
import pannier.ProduitPannier;
 
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class GestionCommandes 
{
    @PersistenceContext(unitName = "SunShopPU")
    private EntityManager em;
    @Resource
    private SessionContext contexte;
    @EJB
    private ProduitFacade produitFacade;
    @EJB
    private CommandeClientFacade commandeClientFacade;
    @EJB
    private ProduitCommandeFacade produitCommandeFacade;
 
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public int ajouterCommande(String nom, String prenom, String email, String tel, String adresse, String numcarte, Pannier pannier) 
    {
        try
        {
            Client client = ajouterClient(nom, prenom, email, tel, adresse, numcarte);
            CommandeClient commande = ajouterCommande(client, pannier);
            ajouterProduitsCommandes(commande, pannier);
            return commande.getId();
        }   
        catch (Exception e) 
        { 
            contexte.setRollbackOnly();
            return 0; 
        }
    }
 
    private Client ajouterClient(String nom, String prenom, String email, String tel, String adresse, String numcarte) 
    {
        Client client = new Client();
        // si je décommente la ligne du dessous ça fonctionne
        // client.setId(1);
        client.setNom(nom);
        client.setPrenom(prenom);
        client.setEmail(email);
        client.setTel(tel);
        client.setAddresse(adresse);
        client.setNoCarte(numcarte);
 
        em.persist(client);
        return client;
    }
 
    private CommandeClient ajouterCommande(Client client, Pannier pannier) 
    {
        CommandeClient commande = new CommandeClient();
        //commande.setId(1);
        commande.setIdClient(client);
        commande.setMontant(BigDecimal.valueOf(pannier.getTotal()));
 
        // on crée un numéro de confirmation
        Random alea = new Random();
        int i = alea.nextInt(999999999);
        commande.setNoConfirmation(i);
 
        em.persist(commande);
        return commande;
    }
 
    private void ajouterProduitsCommandes(CommandeClient commande, Pannier pannier) 
    {
        em.flush();
 
        List<ProduitPannier> produits = pannier.getProduits();
 
        // on boucle sur le pannier pour créer les produits commandés
        for (ProduitPannier ppProd : produits) 
        {
            int idProduit = ppProd.getProduit().getId();
 
            ProduitCommandePK pcPK = new ProduitCommandePK();
            pcPK.setIdCommandeClient(commande.getId());
            pcPK.setIdProduit(idProduit);
 
            // on crée un produit commandé grâce à ProduitCommandePK
            ProduitCommande prodCommande = new ProduitCommande(pcPK);
 
            // on set la quantité
            prodCommande.setQuantite(ppProd.getQuantite());
 
            em.persist(prodCommande);
        }
    }
 
    public Map getDetailsCommande(int idCommande) 
    {
        Map mapCommande = new HashMap();
 
        // on récupère la commande
        CommandeClient commande = commandeClientFacade.find(idCommande);
 
        // on récupère le client
        Client client = commande.getIdClient();
 
        // on récupère tous les produits commandés
        List<ProduitCommande> produitsCommandes = produitCommandeFacade.findByIdCommande(idCommande);
 
        // on récupère les détails de ces derniers
        List<Produit> produits = new ArrayList<Produit>();
 
        for (ProduitCommande op : produitsCommandes) 
        {
            Produit p = (Produit) produitFacade.find(op.getProduitCommandePK().getIdProduit());
            produits.add(p);
        }
 
        // on ajoute le tout dans la map
        mapCommande.put("recordCommande", commande);
        mapCommande.put("client", client);
        mapCommande.put("produitsCommandes", produitsCommandes);
        mapCommande.put("produits", produits);
 
        return mapCommande;
    }
}
L'erreur se produit à la ligne 47, pour la méthode ajouterClient.

Toutes les informations sont bien "setées" mais à la ligne 71, au moment du persist, une exception est levée et le RollBack ligne 54 est effectué. Ce qui est bizarre, c'est que si je set l'id moi-même, cela fonctionne correctement (pourtant il est bien en identity).

Enfin bref, je n'y comprends pas grand chose et j'ai déjà perdu beaucoup de temps à cause de cela...

Merci d'avance à ceux qui auront le temps de jeter un coup d'oeil.
Tenebrous est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2011, 16h17   #2
Candidat au titre de Membre du Club
 
Homme
Inscription : septembre 2009
Messages : 51
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 21
Localisation : Belgique

Informations forums :
Inscription : septembre 2009
Messages : 51
Points : 14
Points : 14
Voilà alors en fait je viens de me rendre compte qu'il n'y a pas d'erreur dans le code (du moins c'est ce que je suis amené à penser).
Je viens de re-débugger une énième fois et si je set moi-même l'id pour la méthode ajouterClient, elle passe nickel. Pareil pour ajouterCommande (qui ne marchait pas non plus), si je set l'id et la date de création moi-même, ça fonctionne sans problème.
Tout ça pour dire qu'en fait, si j'ai bien compris, tous les champs dans ma BDD censés acquérir leur valeur automatiquement ne le font pas. Mes deux id sont en identity mais si je ne les set pas ça ne marche pas (comme si la BDD ne calculait pas leurs valeurs). Pareil pour la date de création présente dans la table "commande_client" de ma BDD et dont la valeur par défaut est "CURRENT_TIMESTAMP".
Auriez-vous une piste ?
Tenebrous est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/01/2012, 06h31   #3
Membre confirmé
 
Avatar de Khaled.Noordin
 
Homme Khaled Ibn Noordin
Inscription : janvier 2005
Messages : 185
Détails du profil
Informations personnelles :
Nom : Homme Khaled Ibn Noordin
Localisation : France

Informations forums :
Inscription : janvier 2005
Messages : 185
Points : 218
Points : 218
Salut
et la génération automatique ça te va pas?
et au passage pour ton expression régulière d’évaluation d'un email, tu as @Email de hibernate qui le fait pour toi(si tu utilise hibernate biensur).
T'as essayé en enlevant toutes les annotations transactionnel de ton code, car jee6 c'est convention prime sur configuration, donc tes méthodes sont naturellement transactionnel de type REQUIRED, ne met aucune info cascading pour voir dans tes entités ou juste MERGE.
__________________
Ce que l'on conçoit bien s'énonce clairement,
Et les mots pour le dire arrivent aisément. Nicolas Boileau
Khaled.Noordin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/01/2012, 12h43   #4
Membre du Club
 
Inscription : juin 2009
Messages : 125
Détails du profil
Informations forums :
Inscription : juin 2009
Messages : 125
Points : 49
Points : 49
As tu essayé de changer la stratégie de génération des clés ? :
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@NotNull
@Column(name = "id")
private Integer id;



Par :
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Basic(optional = false)
@NotNull
@Column(name = "id")
private Integer id;


Pour tester (normalement en auto_increment ça devrait bien être IDENTITY)
Aure7780 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 08h36.


 
 
 
 
Partenaires

Hébergement Web