无法使用JPA @OneToMany关系删除父行

时间:2013-11-28 08:16:36

标签: java-ee jpa eclipselink one-to-many cascade

在我的Java EE应用程序中,我有两个具有这些JPA关系的持久化实体WorklistTask

Worklist实体:

 public class WorkList implements Serializable {
    ...
    @OneToMany(cascade={CascadeType.PERSIST, CascadeType.REMOVE} , mappedBy ="worklist")
    private List<Task> tasks;
    ...
    }

Task实体:

  public class Task implements Serializable {
    ...
    @ManyToOne
    private WorkList worklist;
    ...
    }

我在Worklist中将级联类型指示为:

  cascade={CascadeType.PERSIST, CascadeType.REMOVE}

因此,我可以保留与Worklist相关联的tasksWorklist列表,但是当我尝试删除Worklist时我遇到了问题我有这个例外:

Avertissement: Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461):  
org.eclipse.persistence.exceptions.DatabaseException
Internal Exception:  
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot  
delete or update a parent row: a foreign key constraint fails (`scopedata`.`TASKS`, 
CONSTRAINT `FK_TASKS_WORKLIST_id` FOREIGN KEY (`WORKLIST_id`) REFERENCES `WORKLISTS` 
(`id`))
Error Code: 1451
Call: DELETE FROM WORKLISTS WHERE ((id = ?) AND (version = ?))
bind => [2 parameters bound]
Query: DeleteObjectQuery(WokList{id=bbf05bdb-1314-4b07-9f4e-69898b800c00, creation=Thu
Nov 28 08:39:21 CET 2013, startDate=Thu Nov 07 00:00:00 CET 2013, endDate=Fri Nov 15
00:00:00 CET

另一方面,我可以成功删除Task

这是WorklistManager.java中删除工作清单

的方法
   @Override
     public boolean deleteWorkList(WorkList workList) {
       if (findWorkList(workList)) {
        em.remove(em.merge(workList));
        return true;
    }
    return false;
    }

然后,我在Managed Bean中调用这个方法:

    public String deleteWorkList() {
    workListManagerLocal.deleteWorkList(selectedWorkList);
    return "index";
  }

我正在使用:JPA2Glassfish 3.1.2.2

1 个答案:

答案 0 :(得分:1)

  1. orphanRemoval=true属性添加到您的@OneToMany关系。
  2. 而不是在em.merge()中调用public boolean deleteWorkList(WorkList workList)制作managedWorklist = em.find(Worklist.class, workList.getId()),而不是删除返回的工作清单:em.remove(managedWorklist)并且不要像我们那样打电话给findWorkList()在你的代码中。