0

我有“学生”和“班级”与多对多的关系。中间有一个链接表。

如果我想通过以下方式用 HQL 检索所有学生,一切都很好:

Query queryObject = getSession().createQuery("from Student");
return queryObject.list();          

使用上面的代码,如果有三个学生,我会得到三个学生的列表。

但是,如果我使用标准,那么只要链接表中没有关联就可以了。

Criteria crit =  getSession().createCriteria(Student.getClass());        
return crit.list();

使用第二个代码,只有当链接表为空时,我才会得到三个结果。但是,当我添加关联时,我得到 6 个结果。查看日志,Hibernate 生成了多个选择。这怎么可能?

有人可以解释为什么会这样吗?如何修复条件以便只返回这三个记录一次?

编辑

在学生类中,我以这种方式映射:

@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(
    name="room_student_rel"
    , joinColumns={
        @JoinColumn(name="id_student")
        }
    , inverseJoinColumns={
        @JoinColumn(name="id_room")
        }
    )
private List<Room> rooms;

在房间(班级)中,我以这种方式映射:

@OneToMany(fetch=FetchType.EAGER,  mappedBy="room")
@Fetch(FetchMode.SELECT)
private List<RoomStudent> roomStudents;
4

1 回答 1

3

为了扩展我之前的评论,当 FetchType 设置为 EAGER 时,Hibernate 将尝试使用外连接进行选择。

请参阅以下 2.2.5.5:

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/

有关此内容的含义,请参见此处:

Hibernate Criteria 使用 FetchType.EAGER 多次返回子级

现在,您还可以指定 FetchMode(根据您的条件.setFetchMode("assocFiled",FetchMode.LAZY))将其设置为 JOIN 以外的内容,或者您​​可以使用类似criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);过滤重复项的内容。

理想情况下,您应该避免在实体映射上使用 EAGER,并且在需要急切获取的情况下,使用一些提示或通过 FetchProfile 在实体加载时显式启用它,然后在需要时处理重复项。

于 2013-10-17T17:22:38.153 回答