rena
rena

Reputation: 1278

JPA ManyToMany Inserting duplicate values

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.

Upvotes: 1

Views: 4038

Answers (1)

Apokralipsa
Apokralipsa

Reputation: 2724

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);

Upvotes: 5

Related Questions