【问题标题】:Hibernate Criteria with group by getting error通过获取错误与组休眠标准
【发布时间】:2014-09-02 10:26:49
【问题描述】:

我有这两个引用表的实体 java 类(jos_content 和 jos_article_section)。

@Entity
@Table(name="jos_content", 
uniqueConstraints={@UniqueConstraint(columnNames="id")})
public class ContentEntity implements Serializable {
private int id; 
private Set<ArticleSectionEntity> josArticleSection;    
private String sefUrl;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id", unique = true, nullable = false)
public int getId() {
    return id;
}   
public void setId(int id) {
    this.id = id;
}

@Column(name="sef_url")
public String getSefUrl() {
    return sefUrl;
}
public void setSefUrl(String sefUrl) {
    this.sefUrl = sefUrl;
}

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name="article_id")
public Set<ArticleSectionEntity> getJosArticleSection() {
    return josArticleSection;
}
public void setJosArticleSection(Set<ArticleSectionEntity> josArticleSection) {
    this.josArticleSection = josArticleSection;
}
}


@Entity
@Table(name="jos_article_section", uniqueConstraints=    {@UniqueConstraint(columnNames="id")})
public class ArticleSectionEntity implements Serializable {
private int id; 
private int articleId;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id", nullable=false, length=10)
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}

@Column(name="article_id", nullable=false)
public int getArticleId() {
    return articleId;
}
}

我正在使用带有 group by 的 Criteria 接口,如下所示:

Criteria contentCriteria = session.createCriteria(ContentEntity.class, "content");
// Join two tables (jos_content, jos_article_section) on  jos_content.id =     jos_acticle_section.article_id
contentCriteria = contentCriteria.setFetchMode("josArticleSection", FetchMode.JOIN);
contentCriteria = contentCriteria.add(Restrictions.eq("content.id", storyId));
contentCriteria = contentCriteria.add(Restrictions.eq("content.state",1));          

//Start Group By Clause
PropertyProjection propProjection = Projections.groupProperty("content.id");
contentCriteria = contentCriteria.setProjection(propProjection);
//End Group By

当我运行我的应用程序时,我得到的输出错误如下:

contentCriteria >>>> CriteriaImpl(com.itgd.entity.ContentEntity:content[][content.id=374821, content.state=1]content.id)
14:24:39,649 INFO  [STDOUT] Hibernate: select this_.id as y0_ from jos_content this_  where this_.id=? and this_.state=? group by this_.id
14:24:39,659 ERROR [STDERR] java.lang.ClassCastException: java.lang.Integer cannot be cast to com.itgd.entity.ContentEntity

我该如何解决这个错误,是否可以使用 Criteria 接口保留所有带有 group by 的字段? 如果有人指导我,请告诉我。

【问题讨论】:

  • 您需要像here 这样的结果转换器,或者只是期望结果不是 ContentEntity - 而是投影列的数组。正是异常所说的:"Result is int (content.id) ... not convert to ContentEntity
  • 您好 Radim Kohler,您能简单解释一下吗?
  • 嗨 Radim Kohler,我用过这个:PropertyProjection propProjection = Projections.groupProperty("content.id"); contentCriteria = contentCriteria.setProjection(propProjection); contentCriteria = contentCriteria.setResultTransformer(Transformers.aliasToBean(ContentEntity.class‌​s));并得到所有的值都是空的。

标签: java hibernate


【解决方案1】:

我们可以使用投影来缩小选定列的列表,但是我们必须做出决定

  • 我们会处理以object[] 表示的结果吗?
  • 我们是否会将结果转换为 DTO(如果可能,转换为原始实体)

如果我们要进行转换,我们必须帮助转换器使用列名。通过alias

即可完成
PropertyProjection propProjection = Projections
   .groupProperty("content.id")
       .as("id") // the alias
   ;

contentCriteria
    .setProjection(propProjection)
    .setResultTransformer(Transformers.aliasToBean(ContentEntity.clas‌​‌​s));

List<ContentEntity> groupedEntities = contentCriteria.list();

那么结果将是 ContentEntity 的列表,它只会填充 id。见:

alias()as() 方法只是将投影实例包装在另一个别名的 Projection 实例中。

或者我们可以期待结果为object[]

Object[] results = contentCriteria.list();

扩展:

如果我们想获取路由实体列表,我们可以将当前查询转换为DetachedCriteria

DetachedCriteria grouped = DetachedCriteria.forClass(ContentEntity.class, "grouped")
    // Filter the Subquery
    .add(...
    // SELECT The User Id  
   .setProjection(propProjection)

所以,上面只会返回我们喜欢的ID,主查询会被它们过滤,同时返回完整的对象(无需转换)

Criteria query = session.createCriteria(ContentEntity.class, "content")
    .add( Subqueries.propertyIn("content.id", grouped) );

在这里查看类似的东西:Hibernate Criteria for "in subselect"

【讨论】:

  • 现在有什么异常?不是以前的 ClassCastException 了吧?
  • 它工作但还不够,因为我想获取定义到 ContentEntity.java 文件中的所有字段。对于上述解决方案,我只得到一个字段值,即 ID。另外,我的查询已经改变,它的显示没有连接。
  • 查询结果为:从 jos_content this_ where this_.id=? select this_.id as y0_ from jos_content this_ where this_.id=?而 this_.state=?按 this_.id 分组
  • 没错。这就是您定义的标准 - 仅返回组的 id。如果您想要完整的实体 - 您必须将此标准用作分离的标准,并将它们用于子查询
  • 看,我也帮不上什么忙了。您应该考虑查询应该是什么样子。如果你需要 GROUP BY... 那么你需要预测。但子查询也有帮助。您必须创建内部查询,然后通过它过滤根查询。根查询,以后可以包含一些关联/连接...但我试图回答您的异常:int 不能被视为 ContentEntity.. Hibernate 祝你好运
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-09
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多