论坛首页 Java企业应用论坛

hibernate的多对多映射

浏览 5764 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-02-12  
平时工作中虽然也经常提到多对多的映射,但是在实际操作中运用到还是第一次.

组group和角色role,多对多的映射.

role的映射文件
<hibernate-mapping>
    <class name="com.vtradex.thorn.server.model.security.Role" table="ROLES">
        <id name="id" column="ID" type="long">
            <generator class="native">
                <param name="sequence">role_sequence</param>
                <param name="parameters">START WITH 1000</param>
            </generator>
        </id>
        <property name="code" type="string">
            <column name="CODE" not-null="true" length="50" unique-key="UK_ROLES"/>
        </property>
        <property name="name" type="string">
            <column name="NAME" not-null="true" length="100"/>
        </property>
        <set name="groups" table="GROUP_ROLE" lazy="true" cascade="all-delete-orphan">
            <key column="ROLE_ID"/>
            <many-to-many class="com.vtradex.thorn.server.model.security.Group" column="GROUP_ID"/>
        </set>        
    </class>    	
</hibernate-mapping>


group的映射文件:
<hibernate-mapping>
    <class name="com.vtradex.thorn.server.model.security.Group" table="GROUPS">
        <id name="id" column="ID" type="long">
            <generator class="native">
                <param name="sequence">group_sequence</param>
                <param name="parameters">START WITH 1000</param>
            </generator>
        </id>
        <property name="code" type="string">
            <column name="CODE" not-null="true" length="50" unique-key="UK_GROUP"/>
        </property>
        <property name="name" type="string">
            <column name="NAME" not-null="true" length="100"/>
        </property>
        <set name="roles" table="GROUP_ROLE" lazy="true" cascade="all-delete-orphan">
            <key column="GROUP_ID"/>
            <many-to-many class="com.vtradex.thorn.server.model.security.Role" column="ROLE_ID"/>
        </set>
        <set name="users" table="GROUP_USER" lazy="true">
            <key column="GROUP_ID"/>
            <many-to-many class="com.vtradex.thorn.server.model.security.User" column="USER_ID"/>
        </set>
    </class>
</hibernate-mapping>


页面支持双向操作,即可在角色中添加删除组,也可在组中添加删除角色.

在组中添加角色:

public void addGroupRoles(Long groupId, List<Long> roleIds) {
		Group group = this.commonDao.load(Group.class, groupId);
		List<Role> roles = new ArrayList<Role>();
		for(Long roleId : roleIds){
			roles.add(this.commonDao.load(Role.class, roleId));
		}
		group.getRoles().addAll(roles);
		this.commonDao.store(group);		
	}


组内删除角色:
public void removeGroupRoles(Long groupId, List<Long> roleIds) {
		Group group = this.commonDao.load(Group.class, groupId);
		List<Role> roles = new ArrayList<Role>();
		for(Long roleId : roleIds){
			roles.add(this.commonDao.load(Role.class, roleId));
		}
		group.getRoles().removeAll(roles);
		this.commonDao.store(group);		
	}


执行以上操作后,程序在移除组的角色的时候,同时将角色以及组本身都删除掉了.

如果将映射文件改为:
<set name="groups" table="GROUP_ROLE" lazy="true" cascade="delete">
        <key column="ROLE_ID"/>
        <many-to-many class="com.vtradex.thorn.server.model.security.Group" column="GROUP_ID"/>
</set> 

以及

<set name="roles" table="GROUP_ROLE" lazy="true" cascade="delete">
        <key column="GROUP_ID"/>
        <many-to-many class="com.vtradex.thorn.server.model.security.Role" column="ROLE_ID"/>
</set>


以上配置下,可以正常进行相关的添加删除操作.直接将cascade="delete"去掉,同样可以正常操作.

觉得很纳闷,程序中只是将角色从组中移除,而不是删除角色这个对象.操作过程中应该是将中间表group_role中的记录删除,但是最后却连带把group和role的记录也删除了.

和同事讨论这种现象,同事分析说hibernate在all-delete-orphan情况下,在删除中间表的时候,会判断相关联的对象是否是"孤儿",如果是"孤儿"也会将相关的对象同时删除.
   发表时间:2007-02-12  
改为cascade="all"就可以了。这样就就会把group和roles相互之间的关联关系取消,即删除那张group_role表相应的记录。

如果是cascade="all-delete-orphan"则在完成cascade="all"相同的动作同时,再检查取消关联的对象是否是“孤儿”(orphan就是这个意思),如果是的话,就会把他们删除了,你的就是这种情况。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics