【发布时间】:2018-06-21 07:34:17
【问题描述】:
我想知道我最近遇到的一个案例。假设我们有一个服务方法如下:
@Override
public User addUser(UUID organizationId, User user) {
Organization organization = organizationRepository.findById(organizationId).orElseThrow(IllegalArgumentException::new);
user.setOrganization(organization);
organization.getUsers().add(user);
invitationService.deleteByUserEmail(user.getEmail());
return user;
}
组织由存储库方法提供:
@Repository
public interface OrganizationRepository extends JpaRepository<Organization, UUID> {
Optional<Organization> findById(UUID id);
}
添加用户仅因为存在invitationService.deleteByUserEmail(user.getEmail()); 而起作用。整个方法属于另一个服务,如下所示:
@Override
@Transactional
public void deleteByUserEmail(String userEmail) {
invitationRepository.deleteByUserEmail(userEmail);
}
我不确定我是否正确理解添加用户的工作原理。根据 Hibernate Docs,只有当实体处于托管状态并且更新发生在单个事务中时,才会发生自动更新。如果我的推理是正确的,则会发生以下步骤:
- 当请求到达并到达控制器时,实体管理器(休眠会话)将附加到当前线程。 (?)
- 处理请求的控制器方法,调用organizationService.addUser方法
- Organization 由 findById 方法获取,该方法默认为事务性和只读的(根据 SimpleJpaRepository 实现)。此事务在此之后关闭,但绑定到它的实体管理器仍在运行,并且组织实体仍然受管理。
- 更新发生
- invitationService.deleteByUserEmail(user.getEmail()); 被调用。因为它是事务方法,所以开始了事务。发生删除,提交事务并将所有更改刷新到数据库中,即使是在组织实体中所做的更改。
是否有可能尽管 addUser 方法是非事务性?
【问题讨论】:
标签: java hibernate spring-boot transactions entity