我想刪除在多對多關係中使用hibernate和JPA的孤立實體,但是我發現所有的屬性都是該屬性。 org.hibernate.annotations.CascadeType.DELETE_ORPHAN(即@Cascade(value = {org.hibernate.annotations.CascadeType.DELETE_ORPHAN)),它只適用於一對多關係。如何在多對多關係中使用hibernate和JPA刪除孤立實體?
我想知道是否可以刪除我的多對多關係中的孤兒。
我想刪除在多對多關係中使用hibernate和JPA的孤立實體,但是我發現所有的屬性都是該屬性。 org.hibernate.annotations.CascadeType.DELETE_ORPHAN(即@Cascade(value = {org.hibernate.annotations.CascadeType.DELETE_ORPHAN)),它只適用於一對多關係。如何在多對多關係中使用hibernate和JPA刪除孤立實體?
我想知道是否可以刪除我的多對多關係中的孤兒。
不要使用hibernate,編寫SQl代碼並以基於集合的方式直接在數據庫上運行它。然後修復數據庫結構問題,讓您首先獲得孤立記錄。如果你甚至有孤立的記錄,這是數據庫設計很差的標誌。這是一個一次性修復,不是從應用程序代碼運行的。因爲沒有建立適當的PK/FK關係而感到羞恥。
其實,我做了以下實體測試:
@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_
試試這個:
@ManyToMany(cascade = CascadeType.ALL, orphanRemoval=true, fetch = FetchType.LAZY, mappedBy = "yourObject")
下面的評論說,ManyToMany註釋中沒有這樣的屬性。 – cproinger 2012-10-18 14:47:13
到目前爲止,沒有爲多對多註釋沒有orphanRemoval屬性。我也有同樣的問題。而將其實施到數據庫上的建議無法解決問題。 JPA的整個理念是,而不是在數據庫上實現邏輯,但是通過映射。
從書「臨JPA 2」:
與源端單基數只有關係可以 使孤兒去除,這就是爲什麼orphanRemoval選項在@OneToOne與@OneToMany定義 關係註釋,但 不在@ManyToOne或@ManyToMany註釋中。
這是一個無賴,但沒有JPA自動孤兒刪除ManyToMany。
你完全錯過了這個觀點(正如你在解決樂觀鎖定問題時所做的那樣)。 – 2010-06-17 14:08:54
@Pascal Thivent - 你錯過了這一點。這不是應該從應用程序界面完成的事情。這是一個數據庫問題,應該由正確設計的數據庫來處理。如果我投下了你的一個答案(我真的不知道我是否做了這件事,它並沒有敲響),然後在你的評論中提及,當它與你毫無關係時,我認爲你還處於仇恨狀態比試圖做正確的事。 – HLGEM 2010-06-17 14:27:56
我的評論是關於你所指的虛構的「結構性問題」(你錯過了這一點,我堅持認爲,OP有適當的PK/FK,你只是沒有在物體層面上思考)。然後,不管信不信,我沒有downvote你的上面的答案(隨時聯繫鑽石版主),即使我認爲這個答案是無關緊要的(就像[我的答案] downvote(http://stackoverflow.com/問題/ 2949039 /併發性,問題與隔離讀提交的/ 2949534#2949534))。所以不,我不是在仇恨(但反饋會被讚賞)。 – 2010-06-17 16:22:26