Comment persister @ManyToMany relation - entrée en double ou entité détachée

Je veux enregistrer mes entité relation ManyToMany. Mais j'ai un problème lors de la persistance des processus.

Mes entités :

@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

@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 de Service :

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

Première fois, lorsque j'essaie de conserver un Utilisateur avec UserRoles "ROLE_USER", pas de problème. L'utilisateur et UserRoles et des tables de jointure sont insérés.

Mon problème est que lorsque j'essaie de conserver un deuxième Utilisateur avec le même UserRoles.
- Je vérifier si le UserRoles existe par le trouver (userRolesServices.getUserRoleByName(...)).
Si existe -> ajouter ce UserRoles à la liste des Utilisateurs (id + nom de rôle) sinon je en créer un nouveau (seulement le nom du rôle).

Quand j'essaie de faire persister le deuxième Utilisateur, - je obtenir de l'exception suivante :
", séparé de l'entité de persister : .....UserRoles" (peut-être parce que getUserRoleByName est effectuée dans le cadre d'une autre opération)

Si je n'utilise pas getUserRoleByName (uniquement *nouveau UserRoles("ROLE_USER");*), j'obtiens l'exception suivante :
"...ConstraintViolation : entrée Dupliquée pour "ROLE_NAME' ..."

Alors, comment bien persister une entité avec @ManyToMany relation ?

source d'informationauteur Aure77 | 2012-03-22