hsbljyy
hsbljyy
2009-12-07 17:08
浏览 319
已采纳

Hibernate软删除

问题描述:
先说数据库设计吧,系统中所有的实体表全部都有Status这个属性,Status这个属性的作用是来控制该记录是否已被删除(删除一个实体对象,只是将Status设置成false)。
由于使用了Hibernate,并且通过在Hibernate配置,一个实体类可以load起关联的其他实体。那么,正常情况下并不会有问题,但是当该实体对象持有的其他实体对象被删除了,那么逻辑上,该对象是不应该持有被删除后的对象,但由于,系统只是update了Status属性,而且关联关系仍然存在,并且这些关联关系是通过Hibernate来管理,无法通过(或者说我不想绕过)Hibernate进行删除。

例如,User类有Set属性,Hibernate在加载User对象的时候,也会将Set也加载好,而他们之间的关联关系是通过Hibernate来控制的。假设,用户test有三个角色:sales,finacer跟master。而master后来被删除了,也就是Status属性被设置成了false。但是,User与Role之间的关系,并没有因为master被删除了而消失,于是系统加载test对象的时候,仍然将master对象加载到内存中,这样明显是违背了逻辑,请问这种情况,如何通过Hibernate来解决。

User类:
[code="java"]
public class User extends BaseModel {

/**
 * 
 */
private static final long serialVersionUID = 613756860331359836L;


private Integer userId;
private String username;
private String password;

private Set<Role> roleSet;

/** default constructor */
User() {
}

}
[/code]
Role类:
[code="java"]public class Role extends BaseModel {

/**
 * 
 */
private static final long serialVersionUID = 2041913483578524972L;


private Integer roleId;
private String roleName;
private String roleAlias;

/** default constructor */
Role() {
}

}[/code]

Mapping文件:
User.hbm.xml
[code="xml"]






    <!-- 用户持有的角色 -->
    <set name="roleSet" table="T_User_Role_Link" cascade="all" lazy="false">
        <key column="UserId" />
        <many-to-many column="RoleId" class="Role" outer-join="auto" />
    </set>

    <!-- 创建人 -->
    <many-to-one name="creator" class="User" column="Creator" cascade="all" update="false" />
    <!-- 创建时间 -->
    <property name="createTime" column="CreateTime" type="timestamp" update="false" />
    <!-- 修改人 -->
    <many-to-one name="modifier" class="User" column="Modifier" cascade="all" />
    <!-- 修改时间 -->
    <property name="modifyTime" column="ModifyTime" type="timestamp" />
    <!-- 数据状态 -->
    <property name="status" column="Status" type="enums.type.StatusType" />
</class>


[/code]
Role.hbm.xml
[code="xml"]







    <!-- 创建人 -->
    <many-to-one name="creator" class="User" column="Creator" cascade="all" update="false" />
    <!-- 创建时间 -->
    <property name="createTime" column="CreateTime" type="timestamp" update="false" />
    <!-- 修改人 -->
    <many-to-one name="modifier" class="User" column="Modifier" cascade="all" />
    <!-- 修改时间 -->
    <property name="modifyTime" column="ModifyTime" type="timestamp" />
    <!-- 数据状态 -->
    <property name="status" column="Status" type="enums.type.StatusType" />
</class>

[/code]

[b]问题补充:[/b]
To cwx714,
可能你还是没有理解我的意思。我这样的配置,是全部交给Hibernate来做。也就是说,Hibernate返回的是一个完整的对象,而不是先返回一个单表的User对象,然后再根据与User关联的表中的值去找相应的其他实体的对象。即,从DAO取出来的User对象就已经包含了Set中所有的值。
[b]问题补充:[/b]
我希望是通过Hibernate来配置,而不是硬编码一堆的where语句。否则,这个根本就不是问题。
[b]问题补充:[/b]
而且,我对Role表是有进行缓存的,如果没有办法剔除那些Status=false的值,那么Hibernate还是要缓存所有的记录,这样,如果数据量少的话是没有问题,但是当数据量达到一定程度时,问题就大了。
[b]问题补充:[/b]
To:phenom,
呵呵,我对hibernate实在不熟。但是在我的代码中,Role是没有Set属性的,即,User跟Role是一对多的关系,但是,没有办法从Role获取到所有拥有该角色的User。也就是说,控制方在User这边。
按照你说的,那么,我如果要删除Role对象,我是不是要先查找所有拥有该角色的User,然后遍历列表,删除?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • wshwrf
    wshwrf 2009-12-09 22:14
    已采纳

    你要删除角色?当角色要删除时可能是:所有的角色都没有分配给用户,还有可能是分配了也不管它,反正我是要删除角色,这样自然用户就分配的角色就消失了.
    对于第一个,显然不需要遍历,对于第二个,既然要这样,遍历是必然的.这就像你修改一个用户的权限时,是先删除权限,然后再插入新的权限,还是把把不要的删除,而只添加新的.
    ROLE和USER只是多对一的关系?通常会是多对多的关系吧.






    不使用延迟加载,..........
    这样每个用户都对应自己的角色?
    既然这样的话,你删除一个角色,将其的status设为false,role.setStatus(false)那同时 role.setUser(null);不就OK了?

    点赞 评论
  • cwx714
    紫翎观星 2009-12-07 17:17

    你需要在每个查询方法里加上where status = 1语句。

    点赞 评论
  • wshwrf
    wshwrf 2009-12-08 13:21

    现在的问题是你要删除中间表的关系?如果是这样的话,那控制方在哪,role还是user不管是哪边,都可以,比如控制方在role就是user.hbm.xml--> 时你可以 Role role=session.get();
    role.setUsers(null);这样就删除了中间表的关系.
    或者:从User方删除
    User user=session.get();
    List roleList=user.getRoles();
    for(Role role:roleList){
    role.getUsers.remove(user);
    }

    点赞 评论

相关推荐