本文介绍了Hibernate和多次返回相同项的条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多关于学生和班级的关系。如果我想通过以下方式检索所有使用HQL的学生,那么一切都很好:





  Query queryObject = getSession()。createQuery(from Student); 
返回queryObject.list();

通过上面的代码,如果有三个学生,我会列出三个学生。



然而,如果我使用标准,只要链接表中没有关联就可以。

  Criteria crit = getSession()。createCriteria(Student.getClass()); 
返回crit.list();

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



有人可以解释为什么会发生这种情况吗?如何修复标准以便只返回一条记录?

编辑

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

$ $ p $ $ $ $ $ $ $ $ $ $ b name =room_student_rel
,joinColumns = {
@JoinColumn(name =id_student)
}
,inverseJoinColumns = {
@JoinColumn(name = id_room)
}

私人列表< Room>房间;

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

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


解决方案

为了扩展我以前的评论,Hibernate会尝试当FetchType设置为EAGER时,请选择使用外部联接。



请参阅以下2.2.5.5:



对于此处的含义请参阅此处:





现在您还可以指定一个FetchMode(在您的标准 .setFetchMode(assocFiled,FetchMode.LAZY) )将其设置为除JOIN以外的其他内容,或者您​​可以使用类似于 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 来过滤理想情况下,您应该避免在您的实体映射上使用EAGER,并且在需要提前获取的情况下,使用某些提示或通过FetchProfile在实体加载时显式启用它,然后处理如果需要的话重复。


I've "Student" and "Class" in relation many to many. In between there is a linking table.

If I want to retrieve all the students with HQL in the following way, everything is fine:

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

With the above code if there are three students I get a list of three students.

If I use criterias, however, it's fine only as long as there are no associations in the linking table.

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

With the second code, I get three results only when the linking table is empty. However when I add an association, I get 6 results. Looking at the log, Hibernate generates multiple selects. How is it possible?

Can someone explain why does this happen? How can I fix the criteria in order to return the three records only once?

EDIT

In the Student class I mapped in this way:

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

In the room (class) I mapped in this way:

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

To expand on my previous comment, Hibernate will try to select using an outer join when the FetchType is set to EAGER.

See 2.2.5.5 at the following:

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

For the implications of this see here:

Hibernate Criteria returns children multiple times with FetchType.EAGER

Now you can also specify a FetchMode (on your criteria.setFetchMode("assocFiled",FetchMode.LAZY) ) to set it to something other than JOIN or you can use something like criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); to filter the duplicates.

Ideally you should avoid EAGER on your entity mappings and where eager fetching is required enable it explicitly on entity load using some hint or via FetchProfile and then deal with the duplicates if required.

这篇关于Hibernate和多次返回相同项的条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 19:04