2012-11-21 36 views
1

我在商業項目中使用打開JPA並希望利用級聯Parent-> Child刪除和合並。JPA合併和刪除不會同時級聯到子對象

我嘲笑了一個顯示問題的工作代碼。

我有一個持久的父對象與一些孩子。我正在消除其中一個孩子的關係並傳遞分離的父親進行合併。當提交事務時發出UPDATE語句,試圖用NULL外鍵更新孤兒子。

@Entity 
public class Parent implements Serializable { 
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Integer id; 
     private String desc; 
    //@ElementDependent 
    @OneToMany(mappedBy="parent", 
     cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}/*,orphanRemoval=true, fetch=FetchType.EAGER*/) 
     private List<Child> childs = new ArrayList<Child>(); 

@Entity 
public class Child implements Serializable { 
    @Id private String desc; 

    @ManyToOne 
    private Parent parent; 


    public class StackOverflowTest extends TestCase { 
     private EntityManager em; 
     private static EntityManagerFactory factory = Persistence.createEntityManagerFactory("SSICTest", System.getProperties()); 
     private Parent p; 
     private Child c; 
     private Child c2; 

     public void testRemove() { 
      prepareObjects(); 

      startTr(); 
      em.persist(p); 
      commitTr(); 

      startTr(); 
      p = em.find(Parent.class, p.getId()); 
      em.remove(p); 
      commitTr(); 
     } 
     public void testMerge() { 
      prepareObjects(); 

      startTr(); 
      em.persist(p); 
      commitTr(); 

      //remove on detached 
      Child child = p.getChilds().get(0); 
      p.getChilds().remove(child); 
      child.setParent(null); 
      startTr(); 

      em.merge(p); 
      commitTr(); 

      startTr(); 
      p = em.find(Parent.class, p.getId()); 
      assertEquals(1, p.getChilds().size()); 
      commitTr(); 
     } 
     protected void prepareObjects() { 
      p = new Parent();  
      c = new Child(); 
      c2 = new Child(); 
      p.setDesc("desc"); 
      c.setDesc(Math.random()+""); 
      c2.setDesc(Math.random()+""); 
      p.getChilds().add(c); 
      c.setParent(p); 
      p.getChilds().add(c2); 
      c2.setParent(p); 
     } 
     void commitTr() { 
      em.getTransaction().commit(); 
      em.close(); 
     } 
     void startTr() { 
      em = factory.createEntityManager(); 
      em.getTransaction().begin(); 
     } 
    } 

在上述testRemove的示例工作正常,但testMerge方法並非如我在頂部說明。

如果我刪除對@ElementDependent的評論,它會有所不同。

testRemove失敗,因爲刪除沒有級聯到Child和db引發的參照完整性異常,並且testMerge沒問題。

orphanRemoval = true,fetch = FetchType.EAGER或@ForeignKey(deleteAction = ForeignKeyAction.CASCADE)在子對象 中的反比關係也沒有幫助。

請指教。我真的很感謝你的幫助!

+0

嗨拉爾斯!我添加了這個,但沒有幫助 '@ManyToOne @JoinColumn(name =「PARENT_ID」,nullable = false,referencedColumnName =「ID」) \t私有父親;' – profund

+0

其中是您當前的映射設置?它在persistence.xml文件中嗎?否則據我所知,還需要一些更多的註釋才能使映射工作。屬性映射到哪些數據列的信息在哪裏? (沒有使用「desc」作爲屬性名稱,因爲它是一個保留的SQL字) – Lars

+0

是的,映射在persistence.xml – profund

回答

0
@OneToMany(mappedBy="parent", 
    cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, 
    orphanRemoval=true, fetch=FetchType.EAGER) 
private List<Child> childs = new ArrayList<Child>(); 

@ManyToOne 
private Parent parent; 

將orphanRemoval設置爲true。 See purpose of orphanRemoval

+0

設置orphanRemoval爲true不起作用,正如我所提到的。 UPDATE語句發出,試圖用testMerge方法中的NULL外鍵更新孤兒子! – profund