哪位帮我解决一下关于Hibernate递归映射的现象

10-06-08 aaronbamboo
两张表:域和用户。域可以有子域,用户必须属于域

域和用户:一对多

域使用了递归映射:

@Entity
@Table(name = "itsc_domain_info")
public class ItscDomainInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    public final static String PROPERTY_ORG_NAME = "domainName";

    public final static String PROPERTY_PARENT_ORG = "parentDomain";
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "domain_id")
    private Integer domainId;

    @Column(name = "domain_name")
    private String domainName;

    @Column(name = "domain_type")
    private int domainType;

    @Column(name = "domain_desc")
    private String domainDesc;

    @ManyToOne
    @JoinColumn(name = "parent_domain", referencedColumnName = "domain_id")
    private ItscDomainInfo parentDomain;

    @OneToMany(mappedBy = "parentDomain",  cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<ItscDomainInfo> childDomains;
<p>

用户类:

@Entity
@Table(name = "itsc_user_info")
public class ItscUserInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final String PROPERTY_USER_NAME = "userName";

    public static final String PROPERTY_USER_ROLEID = "roleInfo.roleId";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "user_id")
    private Integer userId;

    @Column(name = "user_name", updatable = false)
    private String userName;

    @Column(name = "user_pwd")
    private String userPwd;

    @Column(name = "user_telephone")
    private String userTelephone;

    @Column(name = "user_position")
    private String userPosition;

    @OneToOne
    @JoinColumn(name = "role_id", referencedColumnName = "role_id")
    private ItscRoleInfo roleInfo;

    @ManyToOne
    @JoinColumn(name = "user_domain", referencedColumnName = "domain_id")
    private ItscDomainInfo domainInfo;
......
}
<p>

测试数据:新建一个域A,再建两个子域B,C;创建一个用户,用户名为“user”,让用户user所属的域为域A,即他的user_domain为域A的domain_id

利用DetachedCriteria查询用户名为user的用户:

 DetachedCriteria detachedCriteria = DetachedCriteria.forClass(this.entityClass);
            // log.debug("this.objectClass:" + this.objectClass);
            detachedCriteria = detachedCriteria.add(Expression.eq(keyName, key));
            List<T> list = this.getHibernateTemplate().findByCriteria(
                    detachedCriteria);
<p>

结果发现,返回的list为两个名都为user的实例,dubug了一下,发现hibernate的确产生了两条拼装过的记录,唯一的不同是两个子域的id,甚是困惑,哪位是否给解释一下?

              

aaronbamboo
2010-06-08 23:13
把我调试的Hibernate生成sql语句贴出来

select this_.user_id as user1_1_3_, this_.user_domain as user7_1_3_, this_.is_locked as is2_1_3_, this_.role_id as role8_1_3_, this_.user_name as user3_1_3_, this_.user_position as user4_1_3_, this_.user_pwd as user5_1_3_, this_.user_telephone as user6_1_3_, itscdomain2_.domain_id as domain1_3_0_, itscdomain2_.domain_desc as domain2_3_0_, itscdomain2_.domain_name as domain3_3_0_, itscdomain2_.domain_type as domain4_3_0_, itscdomain2_.parent_domain as parent5_3_0_, childdomai3_.parent_domain as parent5_5_, childdomai3_.domain_id as domain1_5_, childdomai3_.domain_id as domain1_3_1_, childdomai3_.domain_desc as domain2_3_1_, childdomai3_.domain_name as domain3_3_1_, childdomai3_.domain_type as domain4_3_1_, childdomai3_.parent_domain as parent5_3_1_, itscrolein4_.role_id as role1_0_2_, itscrolein4_.role_desc as role2_0_2_, itscrolein4_.role_name as role3_0_2_ from itsc_user_info this_ left outer join itsc_domain_info itscdomain2_ on this_.user_domain=itscdomain2_.domain_id left outer join itsc_domain_info childdomai3_ on itscdomain2_.domain_id=childdomai3_.parent_domain left outer join itsc_role_info itscrolein4_ on this_.role_id=itscrolein4_.role_id where this_.user_name='aaron'
<p>

感觉第二个left outer join没有道理,没必要再查用户的时候把子域都查出来和用户平级拼装在一起?

aaronbamboo
2010-06-09 00:13
google了一个晚上,原来是QBC查询方式的重复记录问题。可以通过detachedCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);解决。

但是给分页带来一定问题,不知道道友们是怎么解决的?

猜你喜欢