如何解决Spring JPA-我收到错误消息,即使我已将其持久化,该对象也不会持久化
我正在使用Spring boot-我有3个类User
,Role
和UserRole
。我同时保留了角色对象和用户对象,但是我得到错误,指出角色对象没有持久化在User
和UserRole
之间的映射是OnetoMany,在Role
和UserRole
OnetoMany之间。在UserServiceImpl
类中,我保留了Role对象{{1} }
错误是-
roleRepository.save(userRole.getRole());
解决方法
问题在这里。
第一个(也是一个问题)问题以及出现“瞬态错误”的原因是因为您试图保存一个带有尚未连接到休眠状态的实体的实体。
已阅读:Entity Lifecycle Model in Hibernate
Caused by: org.hibernate.TransientPropertyValueException:
object references an unsaved transient instance -
save the transient instance before flushing :
com.bookstore.domain.security.UserRole.role
->
com.bookstore.domain.security.Role
因此,您正在某个地方尝试使用尚未管理的UserRole
保存Role
。
在实体上调用new
时,该实体处于瞬态。 Hibernate不知道如何处理。它没有数据库ID,也不是供hibernate管理的上下文的一部分(进行relevent查询等)。
要管理实体,您需要通过存储库进行保存。
即roleRepo.save(role)
然后,您会注意到它具有一个ID,现在由休眠管理。
@Service
public class UserServiceImpl implements UserService {
@Transactional
@Override
public User CreateUser(User user,Set<UserRole> userRoles) {
User localUser = userRepository.findByUserName(user.getUserName());
if (localUser != null) {
LOG.warn("Username {} already exists",user.getUserName());
} else {
// For each transient UserRole passed in,save the Role.
// Role is now managed.
for (UserRole userRole : userRoles) {
roleRepository.save(userRole.getRole());
LOG.error("inside for {}",userRole.getRole().getRoleName());
}
user.getUserRoles().addAll(userRoles);
localUser = userRepository.save(user);
}
return localUser;
}
}
以上服务可能无法达到您的期望。
您正在获取Role
并将其保存。
然后,您无需将Role
中的UserRole
替换为回购中的托管文件。
也许这行得通吗?
for(UserRole userRole:userRoles) {
//The role is now managed.
Role managedRole = roleRepository.save(userRole.getRole());
//Replace the transient role in the UserRole with a managed Role.
userRole.setRole(managedRole);
}
因此继续保存User
:
user.getUserRoles().addAll(userRoles);
localUser = userRepository.save(user);
UserRoles
(仍然是瞬态的)至少具有托管的Role
。
Cascade.ALL
应该按照您的期望(我不确定)!并保存临时UserRoles,因为Cascade.ALL将保存子UserRole
s。
https://www.baeldung.com/jpa-cascade-types
============================
第二个问题,没有引起问题,但是您可能需要考虑一下:
目前,您有:
User
1:M UserRole
UserRole
M:1 Role
1用户有许多UserRoles。 1个角色有许多UserRoles。
这里的模型只是散发出来。
通常,您会有一些Role实体/数据库条目,可以通过ManyToMany关系与用户相关。
用户注册时,在其Set<Role> userRoles
中被赋予“ USER”角色,而不是为每个用户都以“ USER”为字段创建新角色。
因此,用户通过“联接表” UserRole
与角色有关系。
Spring已经可以为您创建一个联接表。您实际上并不需要在代码中使用UserRole
实体,因为它只包含FK_User和FK_Role。
基本上,您想要:
User
M:M Role
即一个用户可以有很多角色。
对于用户和角色之间的Many:Many关系,只需使用@ManyToMany批注。
要添加角色,请在数据库中搜索以下内容
Role findByRoleName
并将该受管实体添加到用户的角色,然后保留用户。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。