我知道对此有很多问题,但没有一个解决方案对我有帮助。
我正在使用 PrimeFaces 构建一个惰性加载数据表。这意味着这个数据表列表是一个 LazyDataModel 列表,我必须开发一个 LazyDataModel 实现,其中我覆盖了加载方法。所有这些都可以从PrimeFaces 展示中学到,并且在大多数情况下,当数据表只使用数据库中的一个表时(这不是我的情况),它都可以正常工作。
现在,我有两个实体:
@Entity
@Table(name="UNIVERSITY")
public class University {
@Id
@Column(name="ID_UNIVERSITY")
@GeneratedValue(strategy = GenerationType.AUTO ,generator="SQ_UNIVERSITY")
@SequenceGenerator(name="SQ_UNIVERSITY", sequenceName="SQ_UNIVERSITY")
private Long idUniversity;
@Column(name="NAME")
private String name;
@ManyToOne
@JoinColumn(name="ID_DIRECTOR")
private Director director;
@OneToMany(fetch=FetchType.EAGER, mappedBy = "university")
private Set<Students> students = new HashSet<Students>(0);
...
public int getStudentsQty(){
return this.students.size();
}
...
我将使用该getStudentsQty()
方法从我的数据表中填充一列。这是学生实体:
@Entity
@Table(name="STUDENTS")
public class Students
{
@Id
@Column(name="ID_STUDENTS")
@GeneratedValue(strategy = GenerationType.AUTO ,generator="SQ_STUDENTS")
@SequenceGenerator(name="SQ_STUDENTS", sequenceName="SQ_STUDENTS")
private Long idStudent;
@ManyToOne
@JoinColumn(name="ID_UNIVERSITY")
private University student;
@Column(name="NAME")
private String name;
...
这是我的加载实现将使用的搜索方法:
public List<University> find(int startingAt, int maxPerPage,
final String sortField, final SortOrder sortOrder, Map<String, String> filters) {
session = HibernateUtil.getSession();
Criteria criteria =session.createCriteria(University.class);
List<String> aliases = new ArrayList<String>();
if(maxPerPage > 0){
criteria.setMaxResults(maxPerPage);
}
criteria.setFirstResult(startingAt);
addFiltersToCriteria(filters, criteria, aliases);
Order order = Order.desc("name");
if(sortField != null && !sortField.isEmpty()){
if(sortField.contains(".")){
String first = (sortField.split("\\."))[0];
if(!aliases.contains(first)){
criteria.createAlias(first, first);
aliases.add(first);
}
}
if(sortOrder.equals(SortOrder.ASCENDING)){
order = Order.asc(sortField);
}
else if(sortOrder.equals(SortOrder.DESCENDING)){
order = Order.desc(sortField);
}
}
criteria.addOrder(order);
return (List<University>) criteria.list();
}
现在,我的问题。如果我使用FetchType.LAZY
,一切正常,但性能很糟糕,所以我希望使用EAGER
. 如果我使用EAGER
结果将按预期重复并在此处解释。我尝试在实体中实现equals()
和hashCode()
方法以使用最后一个链接中建议的 a 但它没有工作我不知道如何。我也尝试使用with但它不起作用,因为我使用它,它要求加入。University
LinkedHashSet
DISTINCT
Criteria
addOrder
所以,我发现另一个非常有效的建议。基本上,解决方案是进行第二次Criteria
查询,仅搜索原始搜索中包含 ID 的大学。像这样:
private List<University> removeDuplicates(Order order,
List<University> universities) {
Criteria criteria;
List<University> distinct = null;
if(universities.size() > 0){
Set<Long> idlist = new HashSet<Long>();
for(University univ: universities){
idlist.add(univ.getIdUniversity());
}
criteria = session.createCriteria(University.class);
criteria.add(Restrictions.in("id", idlist)) ;
distinct = (List<University>) criteria.list();
return distinct;
}
else{
return universities;
}
}
因此,它将为我的延迟加载分页数据表带来前 100 行。在第一次Criteria
搜索中,它们将针对第一页进行排序,并且在我的第二次搜索之后将出现相同的 100 行Criteria
,但现在它们将是unsorted。这是第一页的正确行,但在第一页内未排序。我不能在第二个中使用“addOder”,Criteria
否则它们会重复。
最奇怪的是:如果我尝试对结果进行排序,Collections.sort
结果会重复!!!如何??毕竟,我怎样才能订购我的结果?
谢谢!!
编辑:学生人数只是一个例子,我需要在另一个场景中获取每个关联实体内的信息。