Reputation: 405
I'm trying to add a default role value when the user register in Spring Security.
I have two models "User" and "Role" linked with a many-to-many relation.
User.java
@NotEmpty
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Role> roles = new HashSet<>();
Role.java
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(length=15, unique=true, nullable=false)
private String role = RoleType.USER.getRole();
data.sql
INSERT INTO ROLE(role) VALUES ('USER');
INSERT INTO USER(email,password) VALUES ('[email protected]','user');
INSERT INTO USER_ROLES(user_id, roles_id) VALUES (1,1);
The idea here is to use the role_id to set the user role, but i would prefer use a String for lisibility. Something like this in one or two lines
INSERT INTO USER_ROLES(user_id, roles) VALUES (1, "ADMIN");
INSERT INTO USER_ROLES(user_id, roles) VALUES (1, "DBA");
Also when I'm trying to create a user from JAVA I need to use the role dao in order to retrieve the corresponding id and I would like to set a new user to "ROLE_USER" by default.
UserDBTest.java
@Before
public void setUp() {
User user = new User();
user.setEmail("[email protected]");
user.setPassword("password");
user.addRole(roleRepository.findOne(1L)); //detached entity passed to persist
user = userRepository.save(user);
}
Upvotes: 0
Views: 2201
Reputation: 16644
You can write the SQL like this:
INSERT INTO USER_ROLES(user_id, roles)
VALUES (1, (SELECT id FROM roles WHERE role='ADMIN'));
The JPA error you are experiencing is because you don't run in a transaction. For example, if you use TestNG you can let your test class extend AbstractTransactionalTestNGSpringContextTests
, and it will work.
Update: If the extra database lookup is a concern, an option would be to store the role name directly in USER_ROLES
table, User.java would then look like:
@ElementCollection
@Enumerated(EnumType.STRING)
private Set<RoleType> roles;
Upvotes: 1
Reputation: 5351
If you want to store Role
as a String, then you can represent it as enum in Java and drop the table altogether.
Then, you may represent the relationship as @OneToMany
between User
and UserRole
.
In UserRole.java
@ManyToOne
@JoinColumn(name = "user_id")
User user;
@Column(name = "role")
@Enumerated(EnumType.STRING) // this tells JPA to store enum name in db
Role role; //role enum
Upvotes: 0