Hibernate:本机 SQL 查询重复列结果

Posted

技术标签:

【中文标题】Hibernate:本机 SQL 查询重复列结果【英文标题】:Hibernate: Native SQL query repeating column results 【发布时间】:2013-01-09 21:23:00 【问题描述】:

我在 Hibernate 环境中执行以下本机 SQL 查询时遇到了一些奇怪的问题:

public List<Object[]> getExcelResults(Integer idSurvey)

    StringBuffer queryString = new StringBuffer();

    //build query string
    queryString.append("select s.idSection, s.description as sectionDescription, ");
    queryString.append("q.idQuestion, q.description as questionDescription, q.type, ");
    queryString.append("a.idAnswer, a.description, ");
    queryString.append("sum(sa.checked), avg(sa.value), count(sl.idSurveyLog) ");
    queryString.append("from surveylog sl ");
    queryString.append("inner join surveyanswerlog sa ");
    queryString.append("on sl.idSurveyLog = sa.idSurveyLog ");
    queryString.append("inner join answer a ");
    queryString.append("on sa.idAnswer = a.idAnswer ");
    queryString.append("inner join question q ");
    queryString.append("on a.idQuestion = q.idQuestion ");
    queryString.append("inner join section s ");
    queryString.append("on q.idSection = s.idSection ");
    queryString.append("where sl.idSurvey = :idSurvey ");
    queryString.append("group by s.idSection, q.idQuestion, a.idAnswer ");
    queryString.append("order by s.idSection, q.idQuestion, a.idAnswer asc; ");

    //create query
    Query query = this.sessionFactory.getCurrentSession().createSQLQuery(queryString.toString());
    query.setInteger("idSurvey", idSurvey);

    return query.list();

如果您查看返回的属性,您会注意到来自三个不同表的三个description 字段。我遇到的问题是a.description 列的值在应该对应于s.descriptionq.description 的数组位置中重复。

例如,如果我有一个结果行,例如:

[1, "Section A", 1, "Question A", 1, 1, "Answer A", 2, 2, 2]

Hibernate 会为该行返回不正确的 Object[],例如:

[1, "Answer A", 1, "Answer A", 1, 1, "Answer A", 2, 2, 2]

起初我认为我需要使用别名,因为所有这些列都具有相同的名称,但正如您从上面的代码中看到的那样,a.description 没有别名。这样做的原因是,如果我为所有三列添加一个别名,我会得到一个读取 Column "description" not found 的 sqlexception。我完全被难住了,就好像代码在嘲笑我一样。

更奇怪的是,如果我从控制台获取生成的 SQL 查询并在 mysql 上运行它,它就可以正常工作。我怀疑我可能有某种错字,但我一直在查看这段代码,以至于我再也看不到任何东西了。

【问题讨论】:

请注意:使用 + 连接查询的部分会更易读、更高效。 【参考方案1】:

您应该对所有查询投影使用addScalar 方法。例如,

  Query query = sessionFactory.getCurrentSession().createSQLQuery(queryString.toString())
    .addScalar("sectionDescription", StandardBasicTypes.STRING)
    .addScalar("questionDescription", StandardBasicTypes.STRING)
    .setInteger("idSurvey", idSurvey);

【讨论】:

谢谢,我正在测试这个,但由于某种原因,我找不到对 StandardBasicTypes 的引用。你知道这是在哪个 Jar 上或设置该类型的另一种方式吗? org.hibernate.type.StandardBasicTypes。它位于核心 jar 文件 hibernate-core-4.1.9.Final.jar 中。也许您使用的是非常旧的版本? 我正在使用第 3 版。我将寻找该版本的等效版本。谢谢。 啊,是的,就是这样。该常量的休眠 3 等效项是 Hibernate.STRING

以上是关于Hibernate:本机 SQL 查询重复列结果的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 已返回零结果,但本机 sql 返回不同

Hibernate 本机查询 - char(3) 列

如何使用 Hibernate 将 SQL 查询的结果最好地映射到非实体 Java 对象?

Hibernate 本机查询:无效的列名错误 SQL-17006

Hibernate:使用@SqlResultSetMapping 映射本机查询的结果集

在 Hibernate 3.2.2 的本机 sql 查询中使用 IN 子句