[英]Hibernate many-to-many mapping and cascade=delete
我有一個映射(只有重要的部分):
<class name="xyz.Role" table="ROLE" lazy="true"> <id name="id" type="java.lang.Integer"> <column name="ROLE_ID"/> <generator class="increment"/> </id> <set name="assignments" lazy="true" table="PERSON_ROLE" cascade="delete" inverse="true"> <key column="ROLE_ID" /> <many-to-many class="xyz.Person" column="PERSON_ID" /> </set> </class>
和
<class name="xyz.Person" table="PERSON" lazy="true"> <id name="Id" type="java.lang.Integer"> <column name="TPP_ID"/> <generator class="increment"/> </id> <set name="roles" lazy="true" table="PERSON_ROLE" cascade="save-update"> <key column="PERSON_ID" /> <many-to-many class="xyz.Role" column="ROLE_ID" /> </set> </class>
使用此映射,當我刪除角色時,也會刪除具有此角色的人員。 我想要實現的是刪除Role時刪除關聯(PERSON_ROLE表中的行)。 有沒有辦法實現這個目標?
Cascade適用於實體級別。 由於Person_Role
未映射為實體,因此級聯無法幫助您AFAIK。
您可以在從Person_Role
到Role
的外鍵上使用數據庫級“on cascade delete”。
或者你可以 - 正如sfussenegger指出的那樣 - 以編程方式刪除關聯。 請注意,由於您在兩個實體上映射了關聯,因此Person_Role
每一行都將在對象模型中出現兩次。 在這種情況下,建議從兩個集合中刪除相關條目,以免破壞對象模型。 然而,Hibernate只會在持久化更改時查看未使用inverse="true"
映射的關聯的結尾。 也就是說,從你的當前映射的關聯刪除,必須從刪除Person.roles
,不Role.assignments
:
for (Person p : role.assignments) {
person.roles.remove(role)
}
或者您可能希望用關聯實體替換多對多映射,在這種情況下,您可以簡單地使用級聯。 這樣您就可以更輕松地向作業添加更多信息。 例如,如果您必須表達“Joe在QA上工作30%,在需求工程師中工作70%”,您可以簡單地將該字段添加到關聯中。
為什么不在刪除角色之前簡單地調用role.getAssignments().clear()
?
for (Person p : role.getAssignments()) {
person.getRoles.remove(role)
}
role.getAssignments.clear();
session.delete(role);
我不是cascade="delete"
忠實粉絲。 每當我想到一段XML能夠刪除整個有價值數據表時,我就會感到這種奇怪的直覺感覺:)
根本不要在Role
方面放置映射。 如果您最終需要此信息,請使用HQL查詢獲取此信息。 即擺脫這個:
<set name="assignments" lazy="true" table="PERSON_ROLE" cascade="delete"
inverse="true">
<key column="ROLE_ID" />
<many-to-many class="xyz.Person" column="PERSON_ID" />
</set>
無論何時你需要角色的人(我認為應該是罕見的)通過以下方式獲得:
SELECT p FROM Person p JOIN p.roles WHERE role=:role
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.