Bonjour,

J'essaye de faire persister mon entité qui possède une relation ManyToMany en base. Malheureusement je rencontre quelques souci.

Déjà voici les entitées :
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
@Entity
@Table(name = "USER")
public class User implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long userId;
 
    @Column(name = "NAME", unique = true, nullable = false)
    String userName;
 
    @Column(name = "FORNAME")
    String userForname;
 
    @Column(name = "EMAIL")
    String userEmail;
 
    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "USER_USER_ROLES", joinColumns = @JoinColumn(name = "ID_USER"), inverseJoinColumns = @JoinColumn(name = "ID_ROLE"))
    List<UserRoles> userRoles = new ArrayList<UserRoles>();
 
    // getter et setter
}
et
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
@Entity
@Table(name = "USER_ROLES")
public class UserRoles implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long userRolesId;
 
    @Column(unique = true, nullable = false, name = "ROLE_NAME")
    String roleName; 
 
    // getter et setter
}
Code pour l'insertion :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
User user = new User();
UserRoles role;
try {
	role = userRolesServices.getUserRoleByName("ROLE_USER"); // find jpql - transaction
} catch (RuntimeException e) {
	LOGGER.debug("No Roles found");
	role = new UserRoles("ROLE_USER"); // create new
}
user.addUserRole(role);
user.setUserName(urlId);
user.setUserForname(fullName);
user.setUserEmail(email);
userServices.createUser(user); // em.persist(user) - transaction
Comme vous pouvez le voir dans le code précédent, la première insertion d'User fonctionne (car le UserRoles n'existe pas, il est crée au moment du persist du User).

En revanche dès le deuxième persist, comme le UserRoles existe déjà, il est récupéré par userRolesServices.getUserRoleByName("ROLE_USER"); (permettant d'avoir l'id). Mais lorsque j'arrive sur userServices.createUser(user); (persist), j'obtiens l'exception suivante :
"detached entity to persist : .....UserRoles" (je pense au faite que le getUserRoleByName s'effectue sur une autre transaction).

Et si je retire le getUserRoleByName (en utilisant directement new UserRoles("ROLE_USER");), j'obtiens l'exception suivante :
"...ConstraintViolation : Duplicated entry for 'ROLE_NAME' ..."


Donc ma question est : comment bien gérer le persist d'une relation @ManyToMany ?