Hibernate 中的级联一对多和多对多

发布于 2024-12-15 19:10:04 字数 2679 浏览 3 评论 0原文

我是休眠新手,我正在尝试理解级联概念。

我已经研究了 hibernate 文档,但有些事情我不清楚:

1)如何在双向一对多关系中使用级联:

所以可以说我有一个父级,并且父级可以有零个或多个子级。

行为应该是: - 如果删除父对象,则其所有子对象也应被删除。 - 应该可以删除单个子项。因此,只应删除父级与该单个子级之间的关系/连接,而不是父级。

我的父级配置文件如下所示:

<class name="Parent" table="Parent">
     <set name="children" table="Child" fetch="select">
            <key>
                <column name="Parent_id" not-null="true" />
            </key>
            <one-to-many class="Child" />
        </set>
</class>

子级配置文件:

<class name="Child" table="Child">
    <many-to-one name="parent" class="Parent" fetch="select">
            <column name="Parent_id" not-null="true" />
    </many-to-one>
</class>

如何指定级联行为(在子级或父级中)? 我的 DAO 如何删除这个 Child? 我想通过正确配置级联它非常简单, 这样像这样的简单删除

public void deleteChild(Child child){
    Transaction tx = session.beginTransaction();    
    session.delete(childObject);
    tx.commit();
}

就足以删除父对象中的连接, 或者 DAO 是否需要以这种方式手动删除连接:

public void deleteChild(Child child){
    Transaction tx = session.beginTransaction();    
    Parent p = child.getParent();
    p.getChildren().remove(p);
    session.delete(childObject);
    session.update(p);
    tx.commit();
}

2)我的第二个问题与第一个问题类似,但这次我使用双向多对多关系:

可以说: - 类用户和用户可以是零个或多个组的成员 - 一个组可以包含零个或多个用户

,因此,如果我删除一个用户,则只应删除该用户及其与该组的关系,而不应删除该用户所属的组,反之亦然。

如果我删除一个组,则仅应删除该组及其与用户的关系,而不应删除该组成员的用户。

用户的配置文件:

<class name="User" table="User">
    <set name="groups" table="UserGroupMember" inverse="true">    <!-- inverse = true, since i want that the Group adds User as member -->    
        <key column="User_id" />         
        <many-to-many column="group_id" class="Group"/>    
    </set> 
</class>

和组的配置:

<class name="Group" table="Groups">
    <set name="users" table="UserGroupMember" inverse="false">        
            <key column="Group_id" />         
            <many-to-many column="User_id" class="User" />    
    </set>
</class>

在这种情况下如何设置级联? 那么 DAO 呢?

简单的 session.delete(group) 是否足够,或者是否需要像这样手动删除关系:

public void deleteGroup(Group group)
{
    Transaction tx = session.beginTransaction();
    for (User u: group.getUsers())
    {
        u.getGroups().remove(group);
        session.update(u);
    }

    group.getUsers().clear();
    session.update(group);
    session.delete(group);
    tx.commit();
}

I'm new in hibernate and I'm trying to understand the cascade concept.

I have studied the hibernate documentation, but some things are unclear to me:

1) How to use cascade in a bidirectional one-to-many Relation:

So lets say I have a Parent, and a parent can have zero or more Children.

The behaviour should be:
- if a Parent-object is deleted, all of its Children should be deleted too.
- It should be possible, to delete a single Child. So only the relation/connection between parent and this single Child should be deleted, but not the Parent.

My Parent config file would look like this:

<class name="Parent" table="Parent">
     <set name="children" table="Child" fetch="select">
            <key>
                <column name="Parent_id" not-null="true" />
            </key>
            <one-to-many class="Child" />
        </set>
</class>

The Child config file:

<class name="Child" table="Child">
    <many-to-one name="parent" class="Parent" fetch="select">
            <column name="Parent_id" not-null="true" />
    </many-to-one>
</class>

How do I specify the cascade behavior (in Child or Parent)?
And how does my DAO delete this Child?
I guess by configurating cascade correctly its quite simple,
so that a simple delete like this

public void deleteChild(Child child){
    Transaction tx = session.beginTransaction();    
    session.delete(childObject);
    tx.commit();
}

is enough to remove also the connection in the parent object,
or does the DAO need to remove the connection by hand in this manner:

public void deleteChild(Child child){
    Transaction tx = session.beginTransaction();    
    Parent p = child.getParent();
    p.getChildren().remove(p);
    session.delete(childObject);
    session.update(p);
    tx.commit();
}

2) My second Question is similar to the first, but this time I use a bidirectional many-to-many relation:

Lets say :
- A class User and a User can be member of zero or more Groups
- A Group can contain zero or more Users

So if I delete a User, then only the User and the relation to the Group should be deleted and not the Groups, in which this User was member and vice versa.

If I delete a Group, than only the Group and the relation to the User should be deleted, but not the Users that were member of this Group.

The config file for User:

<class name="User" table="User">
    <set name="groups" table="UserGroupMember" inverse="true">    <!-- inverse = true, since i want that the Group adds User as member -->    
        <key column="User_id" />         
        <many-to-many column="group_id" class="Group"/>    
    </set> 
</class>

and the config for the Group:

<class name="Group" table="Groups">
    <set name="users" table="UserGroupMember" inverse="false">        
            <key column="Group_id" />         
            <many-to-many column="User_id" class="User" />    
    </set>
</class>

How do i set cascade in this case?
And what about the DAO?

Is a simple session.delete(group) enough or does the relations need to be deleted by hand like this:

public void deleteGroup(Group group)
{
    Transaction tx = session.beginTransaction();
    for (User u: group.getUsers())
    {
        u.getGroups().remove(group);
        session.update(u);
    }

    group.getUsers().clear();
    session.update(group);
    session.delete(group);
    tx.commit();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文