2010-06-16 98 views
19

我想刪除在多對多關係中使用hibernate和JPA的孤立實體,但是我發現所有的屬性都是該屬性。 org.hibernate.annotations.CascadeType.DELETE_ORPHAN(即@Cascade(value = {org.hibernate.annotations.CascadeType.DELETE_ORPHAN)),它只適用於一對多關係。如何在多對多關係中使用hibernate和JPA刪除孤立實體?

我想知道是否可以刪除我的多對多關係中的孤兒。

回答

-9

不要使用hibernate,編寫SQl代碼並以基於集合的方式直接在數據庫上運行它。然後修復數據庫結構問題,讓您首先獲得孤立記錄。如果你甚至有孤立的記錄,這是數據庫設計很差的標誌。這是一個一次性修復,不是從應用程序代碼運行的。因爲沒有建立適當的PK/FK關係而感到羞恥。

+0

你完全錯過了這個觀點(正如你在解決樂觀鎖定問題時所做的那樣)。 – 2010-06-17 14:08:54

+0

@Pascal Thivent - 你錯過了這一點。這不是應該從應用程序界面完成的事情。這是一個數據庫問題,應該由正確設計的數據庫來處理。如果我投下了你的一個答案(我真的不知道我是否做了這件事,它並沒有敲響),然後在你的評論中提及,當它與你毫無關係時,我認爲你還處於仇恨狀態比試圖做正確的事。 – HLGEM 2010-06-17 14:27:56

+0

我的評論是關於你所指的虛構的「結構性問題」(你錯過了這一點,我堅持認爲,OP有適當的PK/FK,你只是沒有在物體層面上思考)。然後,不管信不信,我沒有downvote你的上面的答案(隨時聯繫鑽石版主),即使我認爲這個答案是無關緊要的(就像[我的答案] downvote(http://stackoverflow.com/問題/ 2949039 /併發性,問題與隔離讀提交的/ 2949534#2949534))。所以不,我不是在仇恨(但反饋會被讚賞)。 – 2010-06-17 16:22:26

5

其實,我做了以下實體測試:

@Entity 
public class Person { 
    @Id 
    @GeneratedValue 
    private Long id; 
    private String firstName; 
    private String lastName; 

    @ManyToMany 
    @Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN) 
    private Set<Role> roles = new HashSet<Role>(); 

    //... 
} 

@Entity 
public class Role { 
    @Id 
    @GeneratedValue 
    private Long id; 

    private String name; 

    @ManyToMany(mappedBy = "roles") 
    private Set<Person> persons = new HashSet<Person>(); 

    //... 
} 

並用以下數據集:

<dataset> 
    <PERSON id="1" firstname="john" lastname="doe"/> 
    <PERSON id="2" firstname="clark" lastname="kent"/> 
    <PERSON id="3" firstname="james" lastname="bond"/> 
    <ROLE id="1" name="foo"/> 
    <ROLE id="2" name="bar"/> 
    <ROLE id="3" name="boo"/> 
    <ROLE id="4" name="baz"/> 
    <PERSON_ROLE persons_id="1" roles_id="1"/> 
    <PERSON_ROLE persons_id="1" roles_id="2"/> 
    <PERSON_ROLE persons_id="2" roles_id="2"/> 
    <PERSON_ROLE persons_id="2" roles_id="3"/> 
    <PERSON_ROLE persons_id="3" roles_id="1"/> 
    <PERSON_ROLE persons_id="3" roles_id="4"/> 
</dataset> 

下面的測試方法:

@Test 
public void testCascadeDeleteOrphanOnDelete() { 
    Person person = entityManager.find(Person.class, 1L); 
    entityManager.remove(person); 
    ReflectionAssert.assertPropertyLenientEquals("id", Arrays.asList(2, 3), findAllPersons()); 
    ReflectionAssert.assertPropertyLenientEquals("id", Arrays.asList(3, 4), findAllRoles()); 

} 

private List<Person> findAllPersons() { 
    return entityManager.createQuery("from Person").getResultList(); 
} 

private List<Role> findAllRoles() { 
    return entityManager.createQuery("from Role").getResultList(); 
} 

只是傳遞。下面所產生的輸出:

 
Hibernate: select personx0_.id as id17_0_, personx0_.firstName as firstName17_0_, personx0_.lastName as lastName17_0_ from Person personx0_ where personx0_.id=? 
Hibernate: select roles0_.persons_id as persons1_1_, roles0_.roles_id as roles2_1_, rolex1_.id as id18_0_, rolex1_.name as name18_0_ from Person_Role roles0_ left outer join Role rolex1_ on roles0_.roles_id=rolex1_.id where roles0_.persons_id=? 
Hibernate: delete from Person_Role where persons_id=? 
Hibernate: delete from Role where id=? 
Hibernate: delete from Role where id=? 
Hibernate: delete from Person where id=? 
Hibernate: select personx0_.id as id17_, personx0_.firstName as firstName17_, personx0_.lastName as lastName17_ from Person personx0_ 
Hibernate: select rolex0_.id as id18_, rolex0_.name as name18_ from Role rolex0_ 
+1

是的!我也測試過了。它真的刪除了所有依賴角色(在這種情況下),但我不能這樣做。我只需要刪除孤兒... 感謝您的幫助! – Alucard 2010-06-17 13:50:04

+0

@ user368453:確實,它就像Hibernate級聯DELETE(現在我明白這不是你想要的)。我想知道Hibernate是否可以做得更好。 – 2010-06-17 14:05:12

+0

是的!我希望它可以......但似乎我必須在數據庫上創建一個觸發器來做到這一點=/ – Alucard 2010-06-17 14:38:42

-12

試試這個:

@ManyToMany(cascade = CascadeType.ALL, orphanRemoval=true, fetch = FetchType.LAZY, mappedBy = "yourObject") 
+0

下面的評論說,ManyToMany註釋中沒有這樣的屬性。 – cproinger 2012-10-18 14:47:13

2

到目前爲止,沒有爲多對多註釋沒有orphanRemoval屬性。我也有同樣的問題。而將其實施到數據庫上的建議無法解決問題。 JPA的整個理念是,而不是在數據庫上實現邏輯,但是通過映射。

7

從書「臨JPA 2」:

與源端單基數只有關係可以 使孤兒去除,這就是爲什麼orphanRemoval選項在@OneToOne與@OneToMany定義 關係註釋,但 不在@ManyToOne或@ManyToMany註釋中。

這是一個無賴,但沒有JPA自動孤兒刪除ManyToMany。

相關問題