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

时间:2013-01-09 21:23:00

标签: java mysql sql hibernate

在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没有别名。这样做的原因是,如果我向所有三列添加别名,我会得到一个sqlexception,它读取列“描述”未找到。我完全被难倒了,就好像代码嘲笑我一样。

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

1 个答案:

答案 0 :(得分:2)

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

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