Je travaille actuellement sur une application web utilisant Java EE/EclipseLink et postgreSQL. A propos de mes entités, je gère notamment "Projet", "Utilisateur" et "Droit" (droits d'accès comme lire, écrire, supprimer ...). La relation entre ces entités est la suivante: un projet peut avoir plusieurs utilisateurs qui ont des droits différents sur le projet. Par conséquent, j'ai une triple association: Projet + Utilisateur + Droit.Association triple de persistance JPA/EclipseLink
Je suis confronté à un problème gênant pendant la persistance de cette association. Quand je persiste un projet avec ses informations, tout va bien (c'est dans la DB et je peux l'utiliser dans mon application), j'ai aussi des droits et des utilisateurs persistants. Ensuite, je veux ajouter une association entre eux afin que je crée l'entité d'association appelée ProjectUserRight, je mis le projet, l'utilisateur et le droit des entités existantes, mais quand je persiste, je reçois l'exception ci-dessous:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERREUR: une valeur NULL viole la contrainte NOT NULL de la colonne « id_project »
Error Code: 0
Call: INSERT INTO project_user_right (id_right, id_project, id_user) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery([email protected])
Voici le projet de classe:
@Entity
@Table(name="project")
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_project", unique=true, nullable=false)
private Integer idProject;
//bi-directional many-to-one association to ProjectUserRight
@OneToMany(mappedBy="project", cascade={CascadeType.ALL})
private Set<ProjectUserRight> projetUtilDroits;
...
la classe utilisateur:
@Entity
@Table(name="user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_user", unique=true, nullable=false)
private Integer idUser;
@Column(name="nom_utilisateur", nullable=false, length=50)
private String userName;
//bi-directional many-to-one association to ProjectUserRight
@OneToMany(mappedBy="user")
private Set<ProjectUserRight> projetUtilDroits;
...
la classe A droite:
@Entity
@Table(name="right")
public class Right implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_right", unique=true, nullable=false)
private Integer idRight;
@Column(name="type_right", nullable=false, length=10)
private String typeRight;
//bi-directional many-to-one association to ProjectUserRight
@OneToMany(mappedBy="right")
private Set<ProjectUserRight> projetUtilDroits;
...
Et la classe d'association:
@Entity
@Table(name="project_user_right")
public class ProjectUserRight implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private ProjectUserRightPK id;
//bi-directional many-to-one association to Right
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_right", insertable=false, updatable=false)
private Right right;
//bi-directional many-to-one association to Project
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_project", insertable=false, updatable=false)
private Project project;
//bi-directional many-to-one association to User
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_user", insertable=false, updatable=false)
private User user;
Et le ProjectUserRightPK (édité après commentaire):
@Embeddable
public class ProjectUserRightPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(name="id_project", unique=true, nullable=false)
private Integer idProject;
@Column(name="id_right", unique=true, nullable=false)
private Integer idRight;
...//getters and setters
@Column(name="id_user", unique=true, nullable=false)
private Integer idUser;
j'ai écrit le code suivant pour persister l'association:
Project project = getService(Projet.class).getFromID(projectId);//retrieve the existing project from database with id
User user = getService(Utilisateur.class).getFromID(userId);//retrieve the existing user from database with id
Right right = getService(Right.class).getFromID(rightId);//retrieve the existing right from database with id
if(project !=null && user!=null && right!=null){
ProjectUserRight pud = new ProjectUserRight();
pud.setRight(right);
pud.setProject(project);
pud.setUser(user);
project.getProjectUserRights().add(pud);
right.getProjectUserRights().add(pud);
user.getProjectUserRights().add(pud);
service(ProjetUtilDroit.class).persist(pud);//call the persist function on this entity (works fine with all other entities)
}
J'ai également essayé de fusionner le projet au lieu de persister l'association, mais je ge t la même erreur ... (J'ai aussi vérifié le projet id et il est correctement réglé) Je me demande si c'est l'association qui est mal annotée mais je ne trouve pas la bonne façon de la changer. Donc, j'ai vraiment besoin de votre aide! :-)
Merci d'avance pour vos conseils!
S'il vous plaît ajouter la définition de la classe ProjectUserRightPK –
Fait! En effet, je dois admettre que je n'ai pas regardé dans cette classe en profondeur ... Merci pour votre aide – Coralie