2012-09-21 1 views
0

. 다른 기능을 사용하여 해당 Task을 삭제하겠습니까?JPA OneToMany 양방향 병합은 어떻게 병합됩니까? <code>EntityManger</code> 갱신 <code>Task</code>의 컬렉션을 가지고 ProjectValue이 <code>EntityManger</code> 메모리에 프로그램에 의해 제거 아이 <code>Task</code>을 삭제할 수 없습니다 <code>@OneToMany</code> 양방향에서

DataStructure : 

    In ProjectPlan Table : 
     PRPJ0001, First Poject 
    In Task Table : 
     AAA, AAA, PRPJ0001 
     BBB, BBB, PRPJ0001 
     CCC, CCC, PRPJ0001 
    In Memory : 
     PRPJ0001, First Poject 
      AAA, AAA, PRPJ0001   --> No Changes 
      BBB, Change Name, PRPJ0001 --> Need to update 
             --> Need to delete CCC 
      NEW, NEW, PRPJ0001   --> Need to add 

    Problem : Entity Manger cannot delete CCC; 

    @Entity 
    public class ProjectPlan { 
     @Id 
     private String id; 
     private String name; 
     @OneToMany(mappedBy = "projectPlan", targetEntity = Task.class, cascade = {CascadeType.ALL}) 
     private List<Task> taskList; 

     public ProjectPlan(){} 

     public ProjectPlan(String id, String name, List<Task> taskList) { 
      this.id = id; 
      this.name = name; 
      this.taskList = taskList; 
     } 
     //getter & setter 
    } 

    @Entity 
    public class Task { 
     @Id 
     private String id; 
     private String name; 
     @ManyToOne(targetEntity = ProjectPlan.class, cascade = {CascadeType.REFRESH}) 
     @JoinColumn(name = "projectId", referencedColumnName = "ID") 
     private ProjectPlan projectPlan; 

     public Task(){ 
     } 

     public Task(String id, String name, ProjectPlan projPlan) { 
      this.id = id; 
      this.name = name; 
      this.projectPlan = projPlan; 
     } 
     // getter & setter 
    } 

    public class Test { 
     public static void main(String[] args) { 
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA"); 
      EntityManager em = emf.createEntityManager(); 
      /* 
      Existing Data in Database 
       List<Task> taskList = new ArrayList<Task>(); 
       ProjectPlan plan = new ProjectPlan("PRPJ0001", "First Poject", taskList); 
       Task task1 = new Task("AAA","AAA", plan); 
       Task task2 = new Task("BBB","BBB", plan); 
       Task task3 = new Task("CCC","CCC", plan); 
       taskList.add(task1); 
       taskList.add(task2); 
       taskList.add(task3); 
      */ 

      em.getTransaction().begin(); 
      List<Task> taskList = new ArrayList<Task>(); 
      ProjectPlan plan = em.find(ProjectPlan.class, "PRPJ0001"); 

      /*Task "AAA" no changes*/ 
      Task task1 = new Task("AAA","AAA", plan); 

      /*Task "BBB" updated info*/ 
      Task task2 = new Task("BBB","Change Name", plan); 

      /*Task "CCC" removed*/ 

      /*Task "NEW" newly created*/ 
      Task task3 = new Task("NEW","NEW", plan); 
      taskList.add(task1); 
      taskList.add(task2); 
      taskList.add(task3); 

      plan.setTaskList(taskList); 

      em.merge(plan); 
      em.getTransaction().commit(); 
      em.close(); 
     } 
    } 

Task이 경우 다른 Sub Task List instance (재귀 관계), Task도있을 것입니다 이러한 상황에 직면 해있다. 실용적인 삭제가 필요한 작업을 확인하고 검색해야합니까? JPA이이 기능을 지원해야한다고 생각하십니까?

답변

1

사용 속성 주석 OneToMany에 orphanRemoval.

설명 : 일대일 또는 일대 다 관계 목표 엔티티가 관계로부터 제거

, 그것을 목표 엔티티 제거 작업을 캐스케이드하는 것이 바람직하다. 이러한 대상 엔터티는 "고아"로 간주되며 orphanRemoval 특성을 사용하여 고아가 된 엔터티를 제거해야한다고 지정할 수 있습니다.

@Entity 
public class ProjectPlan { 
    @Id 
    private String id; 
    private String name; 
    @OneToMany(mappedBy = "projectPlan", cascade = {CascadeType.ALL}, orphanRemoval=true) // --> new attribute 
    private List<Task> taskList; 

    public ProjectPlan(){} 

    public ProjectPlan(String id, String name, List<Task> taskList) { 
     this.id = id; 
     this.name = name; 
     this.taskList = taskList; 
    } 
    //getter & setter 
} 

@Entity 
public class Task { 
    @Id 
    private String id; 
    private String name; 
    @ManyToOne(cascade = {CascadeType.ALL}) 
    @JoinColumn(name = "projectId", referencedColumnName = "ID") 
    private ProjectPlan projectPlan; 

    public Task(){ 
    } 

    public Task(String id, String name, ProjectPlan projPlan) { 
     this.id = id; 
     this.name = name; 
     this.projectPlan = projPlan; 
    } 
    // getter & setter 
} 
+0

JPA 2의 새로운 기능입니까? – CycDemo

+0

@CycDemo이 게시물보기 http://stackoverflow.com/questions/4329577/jpa-2-0-orphanremoval-true-vs-on-delete-cascade – Jhonathan

0

양방향 연관은 오너 측과 반대 측이있다. Hibernate는 연관이 있는지를 알기 위해 소유자 측을 본다. 소유자 측은 이 아니며에는 mappedBy 속성이 있습니다. 따라서이 경우 소유자 측은 Task입니다. 당신은 프로젝트 계획에서 작업 CCC를 분리하려는 경우

그래서, 당신은 null로의 projectPlan 필드를 설정해야합니다. 작업 CCC를 삭제하려면 em.remove()을 사용하여 삭제해야합니다.

+0

'작업'에 다른 하위 작업 목록 인스턴스 (재귀 관계)가있는 경우 작업 또한이 상황에 직면하게됩니다. 실용적인 삭제가 필요한 작업을 확인하고 검색해야합니까? 'JPA'가이 기능을 지원해야한다고 생각하십니까? – CycDemo

+0

어떤 기능에 대해 이야기하고 있습니까? 특정 작업을 삭제하려면'em.remove (em.getReference (Task.class, taskId))'를 호출하면됩니다. 어떻게 그게 문제 야? –

관련 문제