Richard Avalos Richard Avalos - 3 months ago 16
MySQL Question

Hibernate: preventing multiple same entries in role table

Whenever I save a user and its role(s) to my database, it also adds an extra row in my Role table.

Each user has many roles and each role can belong to many users).

I have 3 tables in my database:


  • users
    (id, username)

  • roles_users
    (user_id, role_id)

  • roles
    (id, role)



E.g. I have 2 roles in my
Role
table (
ROLE_ADMIN
,
ROLE_USER
), I save a user with the role
ROLE_ADMIN
, my
roles_users
table is updated, but a new row is also created in my
Role
table (I want to prevent this).

There are a couple of ways I could prevent this from happening:


  1. Write a query that only updates my
    user
    and
    roles_users
    table

  2. Set the role-id to the same id as the role-name (basically overwriting the row, I am doing this now)



So my question is, is there a better way to do this with hibernate?

This is my
User
model:

@Entity(name = "users")
public class User{

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "roles_users",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"),
uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "role_id"})})
private Set<Role> roles;

public Long getId() {
return id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public Set<Role> getRoles() {
if (roles == null) {
roles = new HashSet();
}
return roles;
}

public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}


This is my
Role
model:

@Entity(name = "roles")
public class Role {

@Id
//@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;

@ManyToMany(mappedBy = "roles", cascade = CascadeType.PERSIST)
private Set<User> users;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Set<User> getUsers() {
if (users == null) {
users = new HashSet();
}
return users;
}

public void setUsers(Set<User> users) {
this.users = users;
}
}


This is the code I use to save a user and its role:

User user = new User();
Role role = new Role();

user.setUsername("john");
role.setName("Admin");
role.setId(Long.valueOf(1));
role.getUsers().add(user);
user.getRoles().add(role);

userService.saveUser(user);

Answer

The issue is you are creating instance of role then adding user to that and then again from that user instance you are adding same role in last line hence you are having two roles object assign to this user thats why storing two enteries so remove the second last line of code adding role object again and use the following code to save user, it should work for you-

User user = new User();
Role role = new Role();

user.setUsername("john");
role.setName("Admin");
role.setId(Long.valueOf(1));
role.getUsers().add(user);


userService.saveUser(user);

instead of above try with save method of role.

Comments