【发布时间】:2018-08-12 22:38:15
【问题描述】:
我有两个表,用户和角色。角色类似于“ADMIN”、“MANAGER”、“USER”。用户可以拥有的角色。所以在我的java项目中,我的用户是
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
private Integer userId;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "user_roles", joinColumns = @JoinColumn(name =
"user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
//other data and getters and setters
}
我的角色类是这样的
@Entity
@Table(name = "role")
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "role_id")
private Integer roleId;
@Column(name = "role_name",unique=true)
private String role;
//getters and setters
}
假设我手动向角色插入了 3 条记录
INSERT INTO `role` VALUES (1,'ADMIN');
INSERT INTO `role` VALUES (2,'MANAGER');
INSERT INTO `role` VALUES (3,'USER');
现在我想插入到 User 表中,这样只有 user 和 user_roles(join table) 被插入:
例如:
如果我想插入一个 userId=1 和 role={ADMIN,MANAGER} 的用户,应该插入 user 表中的一个条目和 user_roles 表中的 2 个条目,如 (1,1) 和 (1,2)。不应向 Roles 表插入任何内容。我如何做到这一点?
我尝试将 manytomany 更改为 onetomany...另外,我尝试将 cascadeType.all 更改为 CascadeType.MERGE 并分离...它们都没有正常工作... 请帮忙
//更新:
添加与创建/更新用户相关的代码
public User createUser(UserDto account) {
User newUser = new User();
newUser.setPassword(account.getPassword());
newUser.setUsername(account.getUsername());
Set<Role> roles = new HashSet<Role>();
Role role = roleRepository.findByRole(account.getRole());
if (role != null) {
role.setRole(account.getRole());
roles.add(role);
newUser.setRoles(roles);
User savedUser = save(newUser);
return savedUser;
}
return null;
}
@Transactional
public User save(User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
try {
user = userRepository.save(user);
} catch (org.springframework.dao.DataIntegrityViolationException ex) {
log.error(ex.getMessage());
return null;
}
return user;
}
@Override
public User updateUser(String oldUserName, UserDto userDto) {
Optional<User> optionalUser = userRepository.findByUsername(oldUserName);
optionalUser.orElseThrow(() -> new UsernameNotFoundException("User not found"));
// if (optionalUser != null) {
User user = optionalUser.get();
if (user != null) {
Set<Role> roleset = new HashSet<Role>();
if (userDto.getRole() != null && !userDto.getRole().isEmpty()) {
Role role = roleRepository.findByRole(userDto.getRole());
if (role != null) {
roleset.add(role);
}
}
user.setRoles(roleset);
user.setUsername(userDto.getUsername());
user = userRepository.save(user);
return user;
} else
return null;
}
当我尝试使用时
@ManyToMany(cascade = {CascadeType.MERGE,CascadeType.PERSIST}, fetch = FetchType.EAGER)
@JoinTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> roles;
我得到以下异常
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.techjava.springbootsecuritymysql.model.Role
【问题讨论】:
-
您是否尝试过完全删除
cascade?我不完全确定它在这里做了什么。我认为不需要。并且:究竟什么不起作用?是否插入了用户但未插入user_roles中的条目?你有错误吗?插入用户的代码是什么样子的? -
@x4rf41 更新了问题
-
错误状态,您传递的角色已分离(这意味着它不再被休眠实体管理器跟踪)。我认为问题在于,您在事务外部读取角色,然后在事务内部插入关联。可以请尝试两件事:1。将@Transactional 添加到
createUser方法。 2.从@ManyToMany中删除casade(或将其设置为cascade = {} -
嘿@x4rf41 它与您提到的上述步骤一起工作......谢谢......
-
不错。 @stallion我用更多的解释来回答它。如果你能接受就好了
标签: java mysql spring hibernate jpa