【问题标题】:Hibernate: bad performance when removing element from many-to-many relationHibernate:从多对多关系中删除元素时性能不佳
【发布时间】:2009-08-06 06:39:19
【问题描述】:

我必须拥有具有多对多关系的类(用户集和用户)(即每个用户都可以属于一些用户集)。在数据库中有一个用户集表、一个用户表和一个“中间”表 (UsersToUserSets)。 现在,如果我想通过执行从 UserSet 中删除用户

 userSet.getUsers().remove(user);
 session.flush()

Hibernate 首先获取属于 userSet 的 所有 个用户,然后删除一个用户并更新“中间”表。

由于可能有成千上万的用户属于一个 UserSet,这对性能非常不利。有没有办法避免所有用户都被获取?

映射文件的有趣部分如下所示:

<class name="...UserSet"> 
...
    <set name="users" table="T_UM_USERS2USER_SETS">
        <key column="FK_USER_SET_ID" />
        <many-to-many column="FK_USER_ID"
            class="...User" />
    </set>
...
</class>

<class name="...User"> 
...
    <set name="userSets" table="T_UM_USERS2USER_SETS" inverse="true">
        <key column="FK_USER_ID" />
        <many-to-many column="FK_USER_SET_ID" class="...UserSet"  />
    </set>
</class>

【问题讨论】:

    标签: performance hibernate


    【解决方案1】:

    获取特定 UserSet 的所有用户,因为您正在调用 userSet.getUsers().remove(user)。对惰性集合执行任何操作都会导致获取集合。你可以做的是:

    1) 如果 userSets 基数低于用户的基数(例如,给定的用户只属于少数 userSets),您可以切换此关系的反端并调用 user.getUserSets().remove(userSet) - 我假设您要在此处删除association 只是,而不是实际的实体。

    2)您可以定义一个命名的SQL查询来从T_UM_USERS2USER_SETS表中删除关联行并执行它。

    【讨论】:

    • 谢谢,您的第一个建议成功了。我已经尝试过第二个,虽然它本身有效,但在程序的其他部分出现了几个问题(即在同一个会话中,集合与数据库的状态不同,等等) .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 2014-03-26
    • 2011-01-02
    • 1970-01-01
    相关资源
    最近更新 更多