Java Hibernate EntityManager.remove(实体)从数据库和关联中删除记录,但不从实体集合中删除记录
因此,我有两个实体项目和任务计划,在项目实体中,我与任务计划实体有一个@manytomy关联Java Hibernate EntityManager.remove(实体)从数据库和关联中删除记录,但不从实体集合中删除记录,java,hibernate,jpa,Java,Hibernate,Jpa,因此,我有两个实体项目和任务计划,在项目实体中,我与任务计划实体有一个@manytomy关联 @Entity @Table(name = "project") public class Project { @Column(name = "descriptions") private String descriptions; @ManyToMany(cascade = CascadeType.ALL) @JoinTable(name = "project_has_task_plan",
@Entity
@Table(name = "project")
public class Project {
@Column(name = "descriptions")
private String descriptions;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "project_has_task_plan",
joinColumns = {@JoinColumn(name = "project_id")},
inverseJoinColumns = {@JoinColumn(name = "task_plan_id")})
private Set<TaskPlan> taskPlans;
public Set<TaskPlan> getTaskPlans() {
return taskPlans;
}
public void setTaskPlans(Set<TaskPlan> taskPlans) {
this.taskPlans = taskPlans;
}
....
@Entity
@Table(name = "task_plan")
public class TaskPlan {
@GeneratedValue(generator = "idIncrementor")
@GenericGenerator(name = "idIncrementor", strategy = "increment")
@Id
private Long id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;...
目前一切正常,当我试图从任务计划实体中删除任务计划时,坏事情就来了。.entitymanager.remove()正常工作,实体从任务计划表中删除,相关的项目有任务计划表,但是,当我刷新页面并且在项目实体上触发getById时,从任务计划实体中删除的项目仍然在设置任务计划中
我必须提到,二级缓存被完全禁用,清除()或逐出所有()方法不起作用
以下是删除代码:
//TaskPlanService class
@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
@ResponseBody
public void deleteTaskPlan(@PathVariable("id") Long taskPlanId) throws Exception {
this.taskplanFacade.deleteOne(taskPlanId);
}
//TaskPlanFacade class
public void deleteOne(Long taskPlanId) {
taskplanDao.deleteById(taskPlanId);
}
//TaskPlanDao class
@Transactional
@Override
public void deleteById(Long taskPlanId) {
TaskPlan taskPlanFromDbs=this.getById(taskPlanId);
if(taskPlanFromDbs!=null){
taskPlanFromDbs.getTasks().stream().forEach(task -> {//this things
//are associated with the
//taskplan entity but for the moment i don't interract
//with them
task.getBadges().stream().forEach(badge -> {
entityManager.remove(badge);
});
entityManager.remove(task);
});
taskPlanFromDbs.getBadges().stream().forEach(badge -> {
entityManager.remove(badge);
});
entityManager.remove(taskPlanFromDbs);
entityManager.flush();
entityManager.clear();
}
}
作为开发人员,您负责维护实体的所有关系。因此,如果删除
任务计划
,则必须注意将其从与其他实体的任何关联中删除
2.9实体关系:
请注意,应用程序负责维护运行时关系的一致性,例如,当应用程序在运行时更新关系时,确保双向关系的“一方”和“多方”彼此一致
作为开发人员,您负责维护实体的所有关系。因此,如果删除
任务计划
,则必须注意将其从与其他实体的任何关联中删除
2.9实体关系:
请注意,应用程序负责维护运行时关系的一致性,例如,当应用程序在运行时更新关系时,确保双向关系的“一方”和“多方”彼此一致
[披露:我没有调试、尝试执行甚至深入阅读您的代码;我不知道EntityManager是如何创建的,也不知道您正在使用哪个@Transactional] Hibernate(和其他JPA提供程序)通常不会在获取实体后修改它们-对象没有魔法,您仍然可以自由使用自定义集合等。没有任何理由从集合中消失或出现在集合中 使用JPA的概念基于“工作单元”模式,该模式要求将操作拆分为单独的“业务逻辑块”,并在单独的EntityManager中运行这些块。只有当整个工作完成并且EntityManager关闭时(至少在心智模型中;实现的工作方式不同),才会与数据库同步
通过使用扩展实体管理器,您显示的代码会将活动扳手扔进机器中。这些源代码似乎误用了Hibernate,并且可能存在许多问题,包括逻辑问题和连接到并发的问题。通过使用普通的事务性实体管理器,它可以很容易地修复和简化。[披露:我没有调试、尝试执行甚至深入阅读您的代码;我不知道EntityManager是如何创建的,也不知道您使用的是哪种@transactional] Hibernate(和其他JPA提供程序)通常不会在获取实体后修改它们-对象没有魔法,您仍然可以自由使用自定义集合等。没有任何理由从集合中消失或出现在集合中 使用JPA的概念基于“工作单元”模式,该模式要求将操作拆分为单独的“业务逻辑块”,并在单独的EntityManager中运行这些块。只有当整个工作完成并且EntityManager关闭时(至少在心智模型中;实现的工作方式不同),才会与数据库同步 通过使用扩展实体管理器,您显示的代码会将活动扳手扔进机器中。这些源代码似乎误用了Hibernate,并且可能存在许多问题,包括逻辑问题和连接到并发的问题。通过使用普通的事务性实体管理器,它可以很容易地修复和简化。 我已经设置了@persistenceContext(type=PersistenceContextType.TRANSACTION) 然后在ProjectDao类中:
@Transactional
public void updateProject(Project project) {
Project itemFromDbs = this.getById(project.getId());
if (itemFromDbs != null) {
itemFromDbs.setTaskPlans(project.getTaskPlans());
entityManager.merge(itemFromDbs);//so i wont persist a detached entity
entityManager.flush();
}
}
还更改了项目和任务计划实体关联fetchType选项,因此不会出现延迟初始化错误:
@Entity
@Table(name = "project")
public class Project {
@GeneratedValue(generator = "idIncrementor")
@GenericGenerator(name = "idIncrementor", strategy = "increment")
@Id
private Long id;
@Column(name = "name")
private String name;
@Column(name = "descriptions")
private String descriptions;
@ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinTable(name = "project_has_task_plan",
joinColumns = {@JoinColumn(name = "project_id")},
inverseJoinColumns = {@JoinColumn(name = "task_plan_id")})
private Set<TaskPlan> taskPlans;
@实体
@表(name=“项目”)
公共类项目{
@GeneratedValue(generator=“idIncrementor”)
@GenericGenerator(name=“idIncrementor”,strategy=“increment”)
@身份证
私人长id;
@列(name=“name”)
私有字符串名称;
@列(name=“descriptions”)
私有字符串描述;
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(name=“项目有任务计划”,
joinColumns={@JoinColumn(name=“project_id”)},
inverseJoinColumns={@JoinColumn(name=“task\u plan\u id”)}
私人设定任务计划;
谢谢@fdreger:)已解决
我已经设置了@persistenceContext(type=PersistenceContextType.TRANSACTION)
然后在ProjectDao类中:
@Transactional
public void updateProject(Project project) {
Project itemFromDbs = this.getById(project.getId());
if (itemFromDbs != null) {
itemFromDbs.setTaskPlans(project.getTaskPlans());
entityManager.merge(itemFromDbs);//so i wont persist a detached entity
entityManager.flush();
}
}
还更改了项目和任务计划实体关联fetchType选项,因此不会出现延迟初始化错误:
@Entity
@Table(name = "project")
public class Project {
@GeneratedValue(generator = "idIncrementor")
@GenericGenerator(name = "idIncrementor", strategy = "increment")
@Id
private Long id;
@Column(name = "name")
private String name;
@Column(name = "descriptions")
private String descriptions;
@ManyToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinTable(name = "project_has_task_plan",
joinColumns = {@JoinColumn(name = "project_id")},
inverseJoinColumns = {@JoinColumn(name = "task_plan_id")})
private Set<TaskPlan> taskPlans;
@实体
@表(name=“项目”)
公共类项目{
@GeneratedValue(generator=“idIncrementor”)
@GenericGenerator(name=“idIncrementor”,strategy=“increment”)
@身份证
私人长id;
@列(name=“name”)
私有字符串名称;
@列(name=“descriptions”)
私有字符串描述;
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(名称)=