java - 进行多对多时如何添加到一组实体
问题描述
我有以下具有多对多关系的实体
用户实体
@Entity
@Table(name = "users")
public class User {
...
@ManyToMany
@JoinTable(
name = "team_members",
joinColumns = @JoinColumn(name = "team_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<Team> teams;
团队实体
@Entity
@Table(name = "teams")
public class Team {
...
@ManyToMany
@JoinTable(
name = "team_members",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "team_id"))
private Set<User> members;
}
我有这个 UserService
public interface UserService {
UserDTO getById(Integer userId);
...
}
我想在 TeamService 中实现一个方法,如下所示:
@Override
@Transactional
public TeamDTO addMemberToTeam(Integer teamId, Integer userId, User currentUser) {
checkCurrentUserIsAdmin(currentUser);
User user = userService.getById(userId); <-------- PROBLEM LINE
Team team = teamRepository.findById(teamId)
.orElseThrow(() -> new RuntimeException("No such team"));
team.getMembers().add(user);
return TeamDTO.fromTeam(teamRepository.save(team));
}
问题是我有返回 UserDTO 的服务,但为了使关系正常工作,我需要一个用户。
我能想到的可能解决方案:
解决方案1:
在 UserService 中有另一个方法显式返回 User,例如:
User getUserById(Integer userId);
但这不会破坏 UserService 只返回 UserDTO 的想法。是否有这样做的标准方法,并且仍然遵循服务接口的最佳实践来使用 DTO。
解决方案2:
在 UserService 中有另一种方法,例如:
@Override
public void addUserToTeam(Integer userId, Team team) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("No such user"));
user.getTeams().add(team);
team.getMembers().add(user);
userRepository.save(user);
}
并将 TeamService 中的方法更改为:
@Override
@Transactional
public TeamDTO addMemberToTeam(Integer teamId, Integer userId, User currentUser) {
checkCurrentUserIsAdmin(currentUser);
Team team = teamRepository.findById(teamId)
.orElseThrow(() -> new RuntimeException("No such team"));
userService.addUserToTeam(userId,team); <--- THIS NEW METHOD CALL
return TeamDTO.fromTeam(teamRepository.save(team));
}
这似乎是一个更好的解决方案,但我仍然觉得我把它复杂化了。
在我的情况下,哪个是更好的解决方案?
解决方案
如果我理解正确,您尝试遵循的最佳实践是 1@Service
拥有 an @Entity
,这就是为什么您如此努力不userRepository
直接在内部使用的原因TeamService
。
恕我直言,DTO
仅当您与外部方进行通信时才需要,例如当您有一个将 a 返回UserDTO
给消费者而不是返回@Entity
自身的 REST 端点时。在您自己的应用程序和服务的范围内,我认为在您需要的任何地方都可以使用存储库,而不是为自己创建一条强硬的路线而使其变得困难。
以防万一您仍想使用UserDTO
来在服务之间以及与外部方进行通信,我建议这样做。
public class UserDTO {
...
// your fields
...
@JsonIgnore
private User userRecord;
}
这样,您的服务仍然可以访问实际@Entity
,并且当您将此对象返回给 API 使用者时,他们将看不到该字段。
推荐阅读
- python-3.x - * 在 np 数组形状的参数中是什么意思?例如,np.multiply(*arr.shape)?
- amazon-web-services - AWS IoT 事物连接状态不可靠
- c# - 在后台轮询其他 API 并保存数据的类的最佳方法
- html - 按钮中的中心图像
- r - 运行闪亮的交互式文档时如何避免重新加载包?
- python - 你可以在python中将一个数字四舍五入到一个数字的倍数吗?
- html - 将固定位置图像始终保持在视口中心
- python - 每次都下载Visual Studio代码python语言服务器?
- c# - 用户单击集合视图时如何显示图像
- php - 该函数只处理最后寻找的模式。怎么了?