Reputation: 195
I have User entity and Role entity which are generated using JPA Tools. User and Role have many-to-many relationship. I use following code to insert admin, however, no data is inserted into user_role table. Also I notice role class has @JoinTable but user class does not have it. Are there differences?
private void addAdmin() {
User admin = new User();
admin.setDisplayName("admin");
Role role1 = new Role();
role1.setRole("ROLE_SUPER_ADMIN");
Role role2 = new Role();
role2.setRole("ROLE_END_USER");
List<Role> roles = new ArrayList<Role>();
roles.add(role1);
roles.add(role2);
admin.setRoles(roles);
userRepository.save(admin);
}
Following is my User class:
@Entity
@NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="display_name")
private String displayName;
//bi-directional many-to-many association to Role
@ManyToMany(mappedBy="users")
private List<Role> roles;
}
Following is my role class:
@Entity
@NamedQuery(name="Role.findAll", query="SELECT r FROM Role r")
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String role;
//bi-directional many-to-many association to User
@ManyToMany
@JoinTable(
name="user_role"
, joinColumns={
@JoinColumn(name="role_id")
}
, inverseJoinColumns={
@JoinColumn(name="user_id")
}
)
private List<User> users;
}
Upvotes: 3
Views: 2219
Reputation: 51
@Entity
public class User {
@ManyToMany
private List<Role> roles;
}
@Entity
public class Role {
@ManyToMany
private List<User> users;
}
public class Auth {
User newUser = new User("username","password");
userDao.save(newUser);
Role newRole_1 = new Role("ADMIN");
Role newRole_2 = new Role("USER");
roleDao.save(newRole_1);
roleDao.save(newRole_2);
List<Role> roles = roleDao.findAll();
User user = userDao.findOne(user_id); // e.g. Long user_id = 1L;
for (Role role : roles) {
user.getRoles().add(role);
}
userDao.save(user);
}
If you created new objects:
User user = new User();
Role role = new Role();
List<Role> roles = new ArrayList<>();
this objects are transient, and Hibernate doesn't work with them. Hibernate works with persistent objects. Therefore you must use methods save(); findOne(); findAll(); and other.
Upvotes: 0
Reputation: 23552
roles
association in the User
entity is the inverse side of the association (specified by mappedBy
). That means that it is the duty of Role
class to maintain the association, so to make the association changes persistent, you have to modify the owner side as well:
role1.getUsers().add(admin);
role2.getUsers().add(admin);
Anyway, it is a very good convention to always update both sides of bidirectional associations, so that the state of the inverse side also reflects the changes in the owner side. That's why it is a common practice to create helper methods that change both sides of the association:
@Entity
public class User {
//bi-directional many-to-many association to Role
@ManyToMany(mappedBy="users")
private List<Role> roles;
public void addRole(Role role) {
if (!roles.contains(role)) {
roles.add(role);
role.addUser(this);
}
}
}
@Entity
public class Role {
//bi-directional many-to-many association to User
@ManyToMany
@JoinTable(
...
)
private List<User> users;
public void addUser(User user) {
if (!users.contains(user)) {
users.add(user);
user.addRole(this);
}
}
}
Upvotes: 4