1

I have the following model:

@Entity
@Table(name="`tbUser`")
public class User {
    @Id
    @SequenceGenerator(name="tbuser_id_seq",
    sequenceName="tbuser_id_seq",
    allocationSize=1)
    @Column(name="`userId`")
    @GeneratedValue
    private Long id;
    @Column(name="username")
    private String username;
    @Column(name="password")
    private String password;
    @Column(name="nombres")
    private String firstName;
    @Column(name="apellidos")
    private String lastName;
    @Column(name="email")
    private String email;
    @Column(name="`avatarUrl`")
    private String avatarUrl;
    @ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.MERGE)
    @JoinTable(name="`tbUserRole`", 
    joinColumns=@JoinColumn(name="`userId`",referencedColumnName="`userId`"), 
    inverseJoinColumns=@JoinColumn(name="`roleId`",referencedColumnName="`roleId`"))
    private List<Role> roles = new ArrayList<>();
...

@Entity
@Table(name="`tbRole`")
public class Role {
    @Id
    @Column(name="`roleId`")
    @GeneratedValue
    private Long id;
    @Column(name="name")
    String name;
    @ManyToMany(mappedBy="roles")
    private List<User> users = new ArrayList<>();
...

Which is mapped to the following tables:

E-R I tried to insert a user with an existing role in the following two ways:

user.getRoles().add(role) and repository.save(new User())

either way, the role is inserted again in the database.

e.g

If these are the existing Roles in the DB:

ID   Name
1    ADMIN
2    USER

and I insert a user with an ADMIN role, it is inserted again:

ID Name
1  ADMIN
2  USER
3  ADMIN

How can I resolve this?

I've already tried the solution in this post, but did not work.

Community
  • 1
  • 1
rena
  • 1,223
  • 3
  • 17
  • 30

1 Answers1

5

The name of the role is not the identifier of the entity nor is it unique. So, the id of the role object will be null if you do something like :

Role role = new Role();
role.setName("ADMIN");
user.getRoles().add(role);
repository.save(user);

JPA will then assume that you passed a new object and will generate a new id for it based on the @GeneratedValue annotation.

Assuming that you use Spring Data you will need to do something like:

Role role = roleRepository.findByName("ADMIN");
user.getRoles().add(role);
Apokralipsa
  • 2,674
  • 17
  • 28
  • this is what I was looking for.....but one question: can't we just store the role object somewhere in order not to extract it every time from the database? – Csa77 Dec 22 '18 at 08:06