Java 如何在Hibernate/JPA中删除现有记录并在映射/子表上插入新记录
表格Java 如何在Hibernate/JPA中删除现有记录并在映射/子表上插入新记录,java,spring,hibernate,jpa,Java,Spring,Hibernate,Jpa,表格 +--------------+-------------+------------+ | USER | | | | ID | USERNAME | | | 1 | Jon | | | 2 | Bob | | | PROJECT |
+--------------+-------------+------------+
| 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;
...
}
用户{
...
@OneToMany(mappedBy=“user”,cascade=CascadeType.ALL,fetch=FetchType.LAZY,orphan=true)
@Getter@Setter私有集合用户项目;
...
}
计划{
@OneToMany(mappedBy=“project”,cascade=CascadeType.ALL,fetch=FetchType.EAGER,orphan=true)
@Fetch(FetchMode.JOIN)
@Getter@Setter私有集合用户项目;
}
用户项目{
....
@许多酮
@JoinColumn(name=“user\u id”)
@Getter@Setter私有用户;
@许多酮
@JoinColumn(name=“project\u id”)
@Getter@Setter私人项目;
@ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
@JoinTable(name=“user\u project\u role”,
joinColumns={@JoinColumn(name=“user\u project\u id”)},
inverseJoinColumns={@JoinColumn(name=“role\u id”)})
@Getter@Setter私有集角色;
...
}
服务实现方法:
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);
}
public User updateUserDetails(用户用户){
User updateuser=userDAO.findOne(User.getId());
for(Iterator Iterator=UpdateUser.getUserProjects().Iterator();Iterator.hasNext();){
UserProject=iterator.next();
如果(!user.getUserProjects()包含(userProject)){
//我甚至将USER\u PROJECT.USER\u ID约束更改为NOT-NULL,以使此行正常工作
userProject.setUser(null);
}
}
返回userDAO.save(updateUser);
}
“我的UI”为用户提供了添加和删除现有项目的选项
我打算删除并插入到用户_项目中。但是,我无法删除用户的现有项目。Iam只能为用户添加新选择的项目
我做错了什么?
如果不清楚,请发表评论
环境
Hibernate 4.x/JPA,Spring 4.x/Spring数据JPA我假设用户项目映射是一种消费选择,因为角色有其他数据(如果没有,通常不映射该表) 孤儿删除显然无法工作,因为它同时被用户和项目表引用 所以要删除,您需要找到UserProject关联,从user和project的两个集合中删除它,从persistant contect,commit事务中显式删除它 例如:
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;
}
public User updateUserDetails(用户模板){
User toUpdate=EM.find(User.class,template.getId());
Set present=template.getUserProjects();//应该保留这些项目
Set toDel=newhashset(toUpdate.getUserProjects());
toDel.removeAll(present);//差异,因此应删除once
Set newOnes=新哈希集(存在);
newOnes.removeAll(toUpdate.getUserProjects());//新添加
for(UserProject-uP:toDel){
up.getProject().getUserProjects().remove(up);//从每个项目删除对UserProject的引用
toUpdate.getUserProjects().remove(向上);
EM.remove(uP);//删除实际
}
toUpdate.getUserProjects().addAll(新项目);
返回更新;
}
如果您找到要删除的UserProjects,将user和project都设置为null并在不更新列表的情况下删除它(您仍然需要在user-project上调用Em.remove),那么它也可能会起作用(目前还不确定)。首先,在上面的代码中,我没有找到您试图删除UserProject记录的地方 如果试图删除UserProject记录的方法是
updateUserDetails
,那么它是错误的。你能澄清一下吗