举个例子说明这个问题:有一种Entity叫article,另外一种Entity叫tag,一个article可以关联多个tag。在查询article的时候,我们可以使用tag作为查询条件。
比如有一个article "ABC" 关联"tagA"和"tagB"。我们在查询的时候,同时把"tagA"和"tagB"作为查询条件,想要查询出所有标示为"tagA"或者"tagB"的article。这种情况下,使用Hibernate criteria查询时会将article "ABC"作为查询结果返回两次。这是由SQL的join决定的。如果用户要求这种情况下只返回一条记录该怎么做呢?
看了Hibernate的javadoc之后我本来以为“criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)”方法可以解决这个问题,但是经过尝试不行。而且即使可以,据我所知(如果不对请指正),ResultTransformer也只是对查询结果集做手脚,这样会造成分页的问题(本来一页应该有10条记录,但如果仅仅是在查询当前页做distinct,会导致本页只有9条)。所以不得不找其他方法。
给我帮助的是来自以下链接的文章:
http://floledermann.blogspot.com/2007/10/solving-hibernate-criterias-distinct.html
该文章解决的方法基于以下思路:
1. 使用criteria查询的时候不查询整个记录,只查询"distinct(root_entity_id_field)",这样就可以保证查询的结果是唯一的;
2. 再使用一个条件为in (id_lists got from the above query)的查询、并包含该entity的所有字段的语句进行查询,得到的结果就是想要的结果。
代码(from http://floledermann.blogspot.com/2007/10/solving-hibernate-criterias-distinct.html
):
if (queryDate != null) {
// project result to distinct ids,
// including columns used for sorting
criteria.setProjection(Projections.distinct(
Projections.projectionList()
.add(Projections.id())
.add(Projections.property("birthDate"))
));
List list = criteria.list();
// unfortunately we have to copy the ids out of the
// resulting Object[] List
List idlist = new ArrayList<long>();
for (Iterator iditer = list.iterator(); iditer.hasNext();) {
Object[] record = (Object[]) iditer.next();
idlist.add((Long)record[0]);
}
// another Hibernate stupidity: empty Lists cause
// Expression.in to throw an error
if (idlist.size() > 0) {
criteria = getSession().createCriteria(Cat.class);
criteria.add(Expression.in("id", idlist));
}
else {
return new ArrayList();
}
}
分享到:
相关推荐
- **分组**:使用`setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)`或`setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)`进行分组查询。 #### 七、总结 通过本文的介绍,我们可以了解到...
crite.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); ``` 这样处理后的结果集将只包含唯一的根实体对象。 #### 动态查询 在实际应用中,经常会遇到需要根据用户输入动态构建查询条件的情况。以下是一个...
在 Criteria 查询中,添加 `dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 可以确保返回的实体不包含重复。 2. **HTTP和SMTP协议及其端口**: - HTTP(超文本传输协议)通常运行在端口 80 上,用于...
DetachedCriteria 是 Hibernate 中的一种离线查询对象,它可以在不依赖 Session 的情况下生成动态 SQL 语句并进行查询。下面是 DetachedCriteria 查询的详细知识点: 创建 DetachedCriteria 对象 DetachedCriteria...
在Hibernate中,如果需要去除查询结果中的重复项,可以使用`Criteria.DISTINCT_ROOT_ENTITY`作为`ResultTransformer`。这将确保返回的实体集合中没有重复的根实体。例如: ```java Criteria criteria = session....
dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 是 Hibernate 框架中用于去除重复项的方法。Criteria.DISTINCT_ROOT_ENTITY 是一个标记,用于指定结果集的去重方式。在 Hibernate 中,我们可以使用 ...
Hibernate中的Criteria查询可以通过设置ResultTransformer为DISTINCT_ROOT_ENTITY来去除查询结果中的重复实体。`dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 这一行代码的作用是确保返回的实体结果...
在Hibernate中,使用dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)可以去除重复项。 2. HTTP协议及端口、SMTP协议及端口 HTTP(HyperText Transfer Protocol)是一种超文本传输协议,使用80端口。SMTP...
1. **Hibernate离线查询去除重复项**:在Hibernate中,使用Criteria API时,可以设置ResultTransformer为`Criteria.DISTINCT_ROOT_ENTITY`来去除查询结果中的重复实体。 2. **HTTP与SMTP协议及端口**:HTTP是用于...
**解决方案**: 使用`Criteria` API中的`setResultTransformer()`方法,并传递`Criteria.DISTINCT_ROOT_ENTITY`参数,可以有效地去除查询结果中的重复项。 **代码示例**: ```java Criteria criteria = session....
Hibernate 提供了 `dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 来去除查询结果中的重复实体。这会在查询执行后对结果进行处理,确保返回的根实体是唯一的。 2. **HTTP和SMTP协议及端口**: HTTP...
Hibernate框架提供了Criteria接口,可以使用`Criteria.DISTINCT_ROOT_ENTITY`作为结果转换器来去除查询结果中的重复项。 2. HTTP与SMTP协议及其端口: - HTTP(超文本传输协议)默认使用80端口,用于客户端与...
- **解决方案**: 在Hibernate的Criteria API中,可以通过调用`setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)`方法来去除查询结果中的重复项。 #### 二、HTTP与SMTP协议及其端口 - **HTTP**: 超文本传输协议...
Hibernate 提供了一个方便的方法来去除查询结果中的重复实体,即 `dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 这行代码会确保返回的实体结果是唯一的,避免了由于关联查询导致的重复数据。 2. **...
为了实现这一目标,开发者可以使用`Criteria` API中的`setResultTransformer`方法,将查询结果转换器设置为`Criteria.DISTINCT_ROOT_ENTITY`。这一操作会确保查询结果中只包含唯一的实体对象,即使这些对象可能在...
1. **离线查询去除重复项**:在Hibernate的Criteria查询中,使用`dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)`可以去除结果集中重复的根实体。 2. **网络协议与端口**:HTTP协议通常使用80端口,SMTP...