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.description
和q.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 查询的结果最好地映射到非实体 Java 对象?
Hibernate 本机查询:无效的列名错误 SQL-17006