【发布时间】:2016-05-12 19:46:33
【问题描述】:
我遇到了类似的错误
org.springframework.dao.InvalidDataAccessApiUsageException:分离 传递给持久化的实体:com.websopti.wotms.entity.Project;嵌套的 异常是 org.hibernate.PersistentObjectException:分离的实体 传递给坚持:com.websopti.wotms.entity.Project
我在实体上有复合键连接,基本上我有两个实体,一个是 Project,一个是 User,我通过创建另一个名为的实体在它们之间创建了复合键连接ProjectUser 以下是类
用户
public class User extends BaseEntity<Long> implements UserDetails {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
...
@OneToMany(mappedBy="user",fetch=FetchType.LAZY)
private List<ProjectUser> userProjects;
...
getter and setters
}
项目
public class Project extends BaseEntity<Long> {
private static final long serialVersionUID = 7541005803335530236L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
...
@OneToMany(mappedBy="project",fetch=FetchType.LAZY, cascade=CascadeType.ALL)
private List<ProjectUser> projectUsers;
...
}
项目用户
@IdClass(CompositeKey.class)
public class ProjectUser extends BaseEntity<Long> {
private static final long serialVersionUID = 476483195548055916L;
@ManyToOne
@Id
@JoinColumn(name="user_id", referencedColumnName="id")
private User user;
@ManyToOne
@Id
@JoinColumn(name="project_id", referencedColumnName="id")
private Project project;
private ProjectRole role;
...
getter setter
}
复合键
public class CompositeKey implements Serializable {
private static final long serialVersionUID = 2186028617883601307L;
private long user;
private long project;
public CompositeKey() {}
public CompositeKey(long user, long project) {
this.user = user;
this.project = project;
}
public boolean equals(Object object) {
if (object instanceof CompositeKey) {
CompositeKey pk = (CompositeKey)object;
return user == pk.user && project == pk.project;
} else {
return false;
}
}
...
getter setter
}
现在,当我当时创建项目时,如果我设置 List 对象并保存,那么它工作正常,但是当我想更新该项目并设置由代码手动创建并设置的修改列表对象时到项目对象。所以现在当我尝试保存这个修改后的项目对象时,我收到“传递给持久化的分离实体”的错误。
我正在关注并保存这个项目对象 我用于保存项目对象控制器方法的代码,如下所示
@RequestMapping(value="/update", method=RequestMethod.POST)
public String updateProject(@ModelAttribute("project") Project project, HttpServletRequest request, RedirectAttributes redirectAttributes){
try {
project.setIpAddress(CommonUtils.getClientIpAddr(request));
Project oldProject = projectService.findById(project.getId());
List<ProjectUser> newProjectUsers = new ArrayList<ProjectUser>();
List<Integer> selectedIndexes = project.getSelectedRoleIndexes();
List<User> users = project.getTeam();
if(users != null && users.size() > 0){
for (User u : users) {
newProjectUsers.add(new ProjectUser(u, project, ProjectRole.getRole(selectedIndexes.get(users.indexOf(u)))));
}
}
List<ProjectUser> oldProjectUsers = oldProject.getProjectUsers();
for (ProjectUser projectUser : new ArrayList<>(oldProjectUsers)) {
if(!users.contains(projectUser.getUser())){
/*disable all task for user*/
//taskService.disableUserTaskForProject(projectUser.getUser(), oldProject);
/*send remove member form project mail*/
//projectEmailService.sendProjectTeamMemberRemoveEmail(projectUser.getUser(), oldProject);
oldProjectUsers.remove(projectUser);
}else{
ProjectUser pu = newProjectUsers.get(users.indexOf(projectUser.getUser()));
oldProjectUsers.remove(projectUser);
projectUser.setRole(pu.getRole());
oldProjectUsers.add(projectUser);
}
}
List<User> oldTeam = oldProjectUsers.stream().map(pu -> {return pu.getUser();}).collect(Collectors.toList());
for (ProjectUser projectUser : newProjectUsers) {
if(!oldTeam.contains(projectUser.getUser())){
/*send user add in project mail*/
//projectEmailService.sendProjectTeamMemberAddEmail(projectUser.getUser(), oldProject);
oldProjectUsers.add(projectUser);
}
}
//oldProjectUsers = entityManager.merge(oldProjectUsers);
//projectUserService.updateAllProjectUsers(oldProjectUsers);
/*for (ProjectUser projectUser : oldProjectUsers) {
entityManager.merge(projectUser);
}*/
project.setProjectUsers(oldProjectUsers);
//project = entityManager.merge(project);
project = projectService.update(project);
/*old team except admin*/
/*List<User> oldTeam = oldProject.getProjectUsers()
.stream()
.map(pu -> {return pu.getUser();})
.collect(Collectors.toList());
List<User> newTeam = project.getTeam()
.stream()
.filter(u -> u.getRole() != SystemRole.ADMIN)
.collect(Collectors.toList());
project = projectService.update(project);
for (User user : oldTeam) {
if(!newTeam.contains(user)){
disable all task for user
taskService.disableUserTaskForProject(user, project);
send remove member form project mail
projectEmailService.sendProjectTeamMemberRemoveEmail(user, project);
}
}
for (User user : newTeam) {
if(!oldTeam.contains(user)){
send user add in project mail
projectEmailService.sendProjectTeamMemberAddEmail(user, project);
}
}*/
} catch(Exception e) {
e.printStackTrace();
return "redirect:/user/UserDashboard";
}
redirectAttributes.addFlashAttribute("projectId",project.getId());
redirectAttributes.addFlashAttribute("fromUpdate", true);
return "redirect:/user/"+PageTemplate.userDashboard;
}
请帮帮我,我被困在这里
【问题讨论】:
-
你这里有几张桌子?根据实体,我可以看到您必须拥有 User 和 Project 表。您是否还有其他存储用户-项目关系的表。你也可以发布这些表结构吗?
-
是的,我已经发布了上面的所有结构,还有另一个名为 ProjectUser 的实体存储与复合键的关系
标签: java spring hibernate spring-mvc spring-data-jpa