表格
+--------------+-------------+------------+
| USER | | |
| ID | USERNAME | |
| 1 | Jon | |
| 2 | Bob | |
| PROJECT | | |
| ID | PROJECTNAME | |
| 1 | Java | |
| 2 | DevOps | |
| 3 | DotNet | |
| 4 | Testing | |
| 5 | Node | |
| USER_PROJECT | | |
| ID | USER_ID | PROJECT_ID |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
+--------------+-------------+------------+
课程
User{
...
@OneToMany(mappedBy="user", cascade=CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval=true)
@Getter @Setter private Set<UserProject> userProjects;
...
}
Project{
@OneToMany(mappedBy="project", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval=true)
@Fetch(FetchMode.JOIN)
@Getter @Setter private Set<UserProject> userProjects;
}
UserProject{
....
@ManyToOne
@JoinColumn(name = "user_id")
@Getter @Setter private User user;
@ManyToOne
@JoinColumn(name = "project_id")
@Getter @Setter private Project project;
@ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
@JoinTable(name="user_project_role",
joinColumns={@JoinColumn(name="user_project_id")},
inverseJoinColumns={@JoinColumn(name="role_id")})
@Getter @Setter private Set<Role> roles;
...
}
服务实施方法:
public User updateUserDetails(User user){
User updatedUser = userDAO.findOne(user.getId());
for(Iterator<UserProject> iterator = updatedUser.getUserProjects().iterator(); iterator.hasNext();){
UserProject userProject = iterator.next();
if(!user.getUserProjects().contains(userProject)){
//I have even changed the USER_PROJECT.USER_ID constraint to NOT-NULL for this line to work
userProject.setUser(null);
}
}
return userDAO.save(updatedUser);
}
我的用户界面为ADD提供了选项,并为用户提供了现有项目。
我打算删除并插入USER_PROJECT。但是我无法为用户删除现有项目。我只能为User添加新选择的项目。
我在这里做错了什么? 如果不清楚,请评论。
环境 Hiberante 4.x / JPA,Spring 4.x / Spring Data JPA
答案 0 :(得分:1)
我认为UserProject映射是一个很好的选择,因为角色附加数据(如果不是你通常不映射该表)。
孤立删除显然无法正常工作,因为User和Project表都引用了它。
所以要删除,你需要找到UserProject关联,从用户和项目的两个集合中删除它,从持久性的contect,commit transaction中删除它。
例如类似的东西:
public User updateUserDetails(User template){
User toUpdate = EM.find(User.class,template.getId());
Set<UserProject> present = template.getUserProjects();//the ones should be kept
Set<UserProject> toDel = new HashSet<>(toUpdate.getUserProjects());
toDel.removeAll(present); //the difference so the once should be removed
Set<UserProjcet> newOnes = new HashSet<>(present);
newOnes.removeAll(toUpdate.getUserProjects()); //freshly added
for (UserProject uP : toDel) {
up.getProject().getUserProjects().remove(uP); //from each project removing reference to UserProject
toUpdate.getUserProjects().remove(uP);
EM.remove(uP); //removing the actuall
}
toUpdate.getUserProjects().addAll(newOnes);
return toUpdate;
}
如果您发现要删除的UserProjects,将user和项目设置为null并将其删除(您必须仍然在用户项目上调用Em.remove)而不更新列表,它也可能(还不确定)。
答案 1 :(得分:0)
首先,我没有到达您尝试删除上述代码中的UserProject记录的位置。
如果updateUserDetails
是您尝试删除UserProject记录的方法,那么它的错误。你能澄清一下吗。