休眠许多一对多映射和级联=删除
我有一个映射(唯一重要的部分):休眠许多一对多映射和级联=删除
<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>
有了这个映射,当我删除一个角色,很具有此角色的人也被删除。我想要实现的是删除角色时的关联(来自PERSON_ROLE表的行)。有什么办法可以做到这一点?
梯级工程对实体的水平。由于Person_Role
未被映射为实体,级联不能帮助您AFAIK。
您可能在Person_Role
到Role
的外键上使用数据库级“级联删除”。
或者你可以 - 正如sfussenegger指出的那样 - 以编程方式删除关联。请注意,由于您在两个实体上映射了关联,因此Person_Role
中的每一行都会在对象模型中出现两次。在这种情况下,建议从两个集合中删除相关条目,以免破坏对象模型。但是,Hibernate只会查看在持续更改时未与inverse="true"
映射的关联的结尾。也就是说,从你的当前映射的关联删除,必须从Person.roles
删除,不Role.assignments
:
for (Person p : role.assignments) {
person.roles.remove(role)
}
或者您可能希望与一个关联实体,以取代许多一对多的映射,在这种情况下,你可以简单地使用级联。这将允许您更轻松地将更多信息添加到作业。例如,如果您不得不表达“乔在质量保证工作30%和70%为需求工程师”,您可以简单地将该字段添加到关联中。
为什么不在删除角色之前简单地调用role.getAssignments().clear()
?我不是cascade="delete"
的大粉丝。每当我想到XML的片段能够删除整个有价值数据表时,我都会感到这种奇怪的直觉。)
这不起作用。当我有级联=“删除”时,它会删除每个人。如果我删除级联=“删除”,当我删除角色时会出现错误,因为外键约束失败。 – 2010-02-15 13:34:45
外键约束错误应通过在删除前调用.clear()来解决。 – sfussenegger 2010-02-15 13:40:14
不要在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
虽然这对外键约束错误没有帮助。 – sfussenegger 2010-02-15 15:47:14
我不确定。例如,Hibernate可能会将它们设置为null。 – Bozho 2010-02-15 15:59:14
但我相信它不会:) – sfussenegger 2010-02-15 16:36:20
+1,因为@Ula似乎有点吝啬投票。这是一个很好的答案! :) – sfussenegger 2010-02-15 16:15:28