Update dans une table avec un attribut - clé (JSF - JPA)
Bonjour à tous,
je suis en train de faire une appli web et je gère à un moment des rôles que je vais affecter à des utilisateurs. Je parle donc de la page me permettant de gérer les roles (CRUD). La table rôle ne contient qu'une clé qui est son nom.
J'ai utilisé la bibliothèque Primefaces pour faire mon tableau éditable et tout marche sauf lorsque j'édite une ligne avec du contenu différent ( par exemple passer de "Test" à "Test2").
Le problème c'est que j'ai une erreur pour mettre à jour ma bdd quand j'essaie de supprimer et ajouter un role (je ne peux pas faire de update comme je n'ai qu'un attribut-clé).
Voici le code de ma page xhtml :
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
| <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" >
<h:head>
<meta charset="utf-8" />
<title>GlassField - Gestion Rôle</title>
<h:outputStylesheet library="default" name="css/form.css"/>
</h:head>
<h:body>
<h:form id="formulaire">
<p:growl id="messages" showDetail="true"/>
<p:panel header="Création de Rôle">
<h:outputLabel for="nom">Nom du rôle <span class="requis">*</span></h:outputLabel>
<p:inputText id="nom" value="#{gestionRoleBean.role.nom}" size="20" maxlength="30">
<p:ajax event="blur" render="nomMessage" update=":formulaire:messages"/>
<f:validator binding="#{existenceRoleValidator}" />
</p:inputText>
<h:message id="nomMessage" for="nom" errorClass="erreur" /><br />
<h:messages globalOnly="true" infoClass="info" />
<p:commandButton value="Créer" action="#{gestionRoleBean.creation}" styleClass="sansLabel">
<f:ajax execute="@form" render="@all" listener="#{gestionRoleBean.creation}" update=":formulaire:messages listeRoles"/>
</p:commandButton>
<br />
</p:panel>
<br />
</h:form>
<h:form id="formulaire2">
<p:growl id="messages" showDetail="true"/>
<p:dataTable var="rolesV" value="#{gestionRoleBean.roles}" id="listeRoles" editable="true">
<f:facet name="header">
Gestion des modèles existants
</f:facet>
<p:ajax event="rowEdit" listener="#{gestionRoleBean.onEdit}" update=":formulaire2:messages" />
<p:ajax event="rowEditCancel" listener="#{gestionRoleBean.onCancel}" update=":formulaire2:messages" />
<!--p:ajax event="rowEdit" update="listeRoles" listener="#{gestionRoleBean.changement}" /> -->
<p:column headerText="Nom" style="width:30%">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{rolesV.nom}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{rolesV.nom}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Options" style="width:5%">
<p:rowEditor />
<p:commandLink action="#{gestionRoleBean.supprimer(rolesV)}" update="@form :formulaire2:messages" process="@this" ajax="true">
<span class="ui-icon ui-icon-trash"></span>
</p:commandLink>
</p:column>
</p:dataTable>
</h:form>
</h:body>
</html> |
Ici le Bean :
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
| package com.sgg.beans;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import org.primefaces.event.RowEditEvent;
import com.sgg.dao.RoleDao;
import com.sgg.entities.Role;
@ManagedBean
@RequestScoped
public class GestionRoleBean implements Serializable {
private static final long serialVersionUID = 1L;
private Role role;
private List<Role> roles;
// Injection de notre EJB (Session Bean Stateless)
@EJB
private RoleDao roleDao;
@PostConstruct
public void init() {
refreshRolesList();
}
// Initialisation de l'entité utilisateur
public GestionRoleBean() {
role = new Role();
}
// Méthode d'action appelée lors du clic sur le bouton duformulaire
// d'inscription
public void creation() {
roleDao.creer( role );
FacesMessage message = new FacesMessage( "Succès de la création !", role.getNom() );
FacesContext.getCurrentInstance().addMessage( null, message
);
}
public Role getRole() {
return role;
}
public void setRole( Role role ) {
this.role = role;
}
public List<Role> getRoles() {
return roles;
}
public void onEdit( RowEditEvent event ) {
changer( (Role) event.getObject() );
FacesMessage msg = new FacesMessage( "Rôle modifié", ( (Role) event.getObject() ).getNom() );
FacesContext.getCurrentInstance().addMessage( null, msg );
}
public void onCancel( RowEditEvent event ) {
FacesMessage msg = new FacesMessage( "Rôle non modifié", ( (Role) event.getObject() ).getNom() );
FacesContext.getCurrentInstance().addMessage( null, msg );
}
public void supprimer( Role role ) {
System.out.println( "Role récupéré supp :" + role.getNom() );
roleDao.supprimer( role );
FacesMessage msg = new FacesMessage( "Rôle supprimé", role.getNom() );
FacesContext.getCurrentInstance().addMessage( null, msg );
}
public void changer( Role role ) {
System.out.println( "Role récupéré modif :" + role.getNom() );
roleDao.changer( role );
}
public void refreshRolesList() {
if ( roles != null ) {
roles.clear();
}
roles = roleDao.getAllRoles();
}
} |
Le Dao :
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
| package com.sgg.dao;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import com.sgg.entities.Role;
@Stateless
public class RoleDao {
private static final String JPQL_SELECT_PAR_NOM = "SELECT r FROM Role r WHERE r.nom=:nom";
private static final String JPQL_SELECT_ALL = "SELECT r FROM Role r";
private static final String PARAM_NOM = "nom";
// Injection du manager, qui s'occupe de la connexion avec la BDD
@PersistenceContext( unitName = "bdd_sgg_PU" )
private EntityManager em;
// Enregistrement d'un nouvel utilisateur
public void creer( Role role ) throws DAOException
{
try {
em.persist( role );
} catch ( Exception e ) {
throw new DAOException( e );
}
}
// Recherche d'un utilisateur à partir de son adresse email
public Role trouver( String nom ) throws DAOException {
Role role = null;
Query requete = em.createQuery( JPQL_SELECT_PAR_NOM );
requete.setParameter( PARAM_NOM, nom );
try {
role = (Role) requete.getSingleResult();
} catch ( NoResultException e ) {
return null;
} catch ( Exception e ) {
throw new DAOException( e );
}
return role;
}
// recuperation des roles
public List<Role> getAllRoles() throws DAOException {
List<Role> roles = null;
Query requete = em.createQuery( JPQL_SELECT_ALL );
try {
roles = requete.getResultList();
} catch ( NoResultException e ) {
return null;
} catch ( Exception e ) {
throw new DAOException( e );
}
return roles;
}
public void changer( Role role ) throws DAOException {
try {
// em.merge( role );
em.remove( em.merge( role ) );
em.flush();
em.persist( role );
} catch ( Exception e ) {
throw new DAOException( e );
}
}
public void supprimer( Role role ) throws DAOException {
try {
em.remove( em.merge( role ) );
} catch ( Exception e ) {
throw new DAOException( e );
}
}
} |
Et enfin l'entité :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.sgg.entities;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
@Entity
public class Role {
@Id
@NotNull( message = "Veuillez saisir un nom de rôle" )
private String nom;
public String getNom() {
return nom;
}
public void setNom( String nom ) {
this.nom = nom;
}
} |
J'espère que vous pourrez m'aider. Merci d'avance et n'hésitez pas à me poser des questions si je n'ai pas été assez clair sur certains points.
(Si vous pouviez m'aiguiller sur comment rafraîchir le second formulaire lors d'une action modifiant la BDD ca serait rudement sympa :) )
Pour info ce que j'utilise : Glassfish 4, BDD Oracle, EclipseLink et JSF