2017-05-08 2 views
1

Dans mon projet, j'ai une entité User et une entité UserRole. Selon ma conception de base de données, un utilisateur peut jouer plusieurs rôles et un rôle peut être associé à plusieurs utilisateurs. Les rôles utilisateur que j'ai dans mon système sont USER et ADMIN.Création d'une base de données pour User, UserRole - relation many to many

Les rôles utilisateur doivent être stockés dans la table et doivent être référés lorsqu'un utilisateur est conservé dans sa table.

Cependant, selon le code que j'ai implémenté, les enregistrements sont également insérés dans la table de rôles utilisateur chaque fois que j'insère un utilisateur dans la base de données. Ce dont j'ai besoin, c'est d'insérer des données dans la table User et dans la table de jointure.

Ce sont mes entités.

utilisateur:

@Entity 
@Table(name="user") 
public class User { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", nullable = false, updatable= false) 
    private Long id; 

    @Column(name = "email", nullable = false, unique = true) 
    private String email; 

    @Column(name = "first_name", nullable = false) 
    private String firstName; 

    @Column(name = "last_name", nullable = false) 
    private String lastName; 

    @Column(name = "password_hash", nullable = false) 
    private String passwordHash; 

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @JoinTable(name = "user_with_role", 
      joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")}, 
      inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}) 
    private List<UserRole> roles; 

} 

UserRole:

@Entity 
@Table(name = "userrole") 
public class UserRole { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", nullable = false, updatable= false) 
    private long id; 

    @Column(name = "role_name") 
    @NotNull 
    @Enumerated(EnumType.STRING) 
    private Role roleName; 

    @ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY) 
    private List<User> users; 
} 

Voici comment je persiste un utilisateur à la base de données.

List<UserRole> roles = new ArrayList<>(); 

UserRole ur_user = new UserRole(); 
ur_user.setRoleName(Role.USER); 

UserRole ur_admin = new UserRole(); 
ur_user.setRoleName(Role.ADMIN); 

roles.add(ur_user); 
roles.add(ur_admin); 

newUser.setRoles(roles); 
entityManager.persist(newUser); 

entityManager.flush(); 

Ce mécanisme convient aux situations dans lesquelles l'associé doit être entré dans la base de données avec l'entité parente. (Par exemple: Numéro de contact des employés)

Dans ma situation, je ne comprends vraiment pas la façon dont je devrais écrire le code afin de ne pas insérer dans la table UserRole lorsqu'un utilisateur est persistant.

Comment dois-je écrire le code dans ma situation. En outre, je voudrais savoir ce que CascadeType I devrait utiliser dans l'entité Utilisateur. J'ai mis CascadeType.ALL, mais je sais que ce n'est pas le meilleur type à cet endroit en fonction du contexte.

Répondre

1

Eh bien en ce qui concerne @ManyToMany vous devriez certainement être très caucios environ CascadeType.REMOVE donc je définirais cela comme CascadeType.PERSIST, CascadeType.MERGE.

Maintenant, vous pouvez conserver le reste des mappages car ils vont bien. Afin de ne pas avoir les rôles sauvegardés, vous devez d'abord les rechercher et ne pas les créer à la main comme vous le faites. Pour la persistance, fournissez juste quelques nouvelles entités non gérées et essayez de les persister lors de la validation.

L'exemple suivant profite de déjà existant UserRole's et grâce à cela que le User persistée (en utilisant les dépendances déjà existantes):

UserRole ur_user = entityManager.getRoleByType(Role.USER); 
UserRole ur_admin = entityManager.getRoleByType(Role.ADMIN); 

roles.add(ur_user); 
roles.add(ur_admin); 

newUser.setRoles(roles); 
entityManager.persist(newUser);