我正在尝试在 JPA 查询中使用分组依据。假设我有一个类 Teacher
和一个类 Student
。一个 Teacher
可以有多个 Student
,一个 Student
只能有一个 Teacher
(一对多)。
以下 JPA 查询:
Query q = this.em.createQuery( "SELECT teacher, COUNT(student)" +
" FROM StudentJpa student" +
" JOIN student.teacher teacher" +
" GROUP BY teacher" +
" ORDER BY COUNT(student) DESC");
生成以下 SQL 查询:
select
teacherjpa1_.teacher_id as col_0_0_,
count(studentjpa0_.id) as col_1_0_,
teacherjpa1_.teacher_id as teacher1_0_,
teacherjpa1_.name as name0_
from
student studentjpa0_
inner join
teacher teacherjpa1_
on studentjpa0_.teacher_id=teacherjpa1_.teacher_id
group by
teacherjpa1_.teacher_id
order by
count(studentjpa0_.id) DESC
在 PostgreSQL 9.0 上我得到以下错误:
org.postgresql.util.PSQLException: ERROR: column "teacherjpa1_.name" must appear in the GROUP BY clause or be used in an aggregate function
同样的错误在PostgreSQL 9.1中没有出现。
谁能解释一下为什么?似乎 JPA 以错误的方式生成组:它应该包括所有 Teacher
属性,而不仅仅是 id。
如果需要,这是我的 JPA/Hibernate/DB 配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:property-placeholder location="/WEB-INF/jdbc.properties" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<constructor-arg>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
</constructor-arg>
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="showSql" value="${db.showSql}" />
<property name="generateDdl" value="${db.generateDdl}" />
</bean>
<!-- enabling annotation driven configuration /-->
<context:annotation-config />
<context:component-scan base-package="my.package" />
<!-- Instructs the container to look for beans with @Transactional and decorate them -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<!-- FactoryBean that creates the EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
<!-- A transaction manager for working with JPA EntityManagerFactories -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
谢谢!
更新 - 一种解决方案是指定 GROUP BY teacher.id, teacher.name
而不是 GROUP BY teacher
,但事实并非如此方便的。有更好的解决方案吗?
最佳答案
该查询在 PostgreSQL 9.1 版中生效。看来您在本地使用的是 PostgreSQL 9.1 版,而 Heroku 使用的是更早的版本。
请参阅 9.1 发行说明:
http://www.postgresql.org/docs/9.1/interactive/release-9-1.html
在该页面的“查询”部分下,它显示:
Allow non-GROUP BY columns in the query target list when the primary key is specified in the GROUP BY clause (Peter Eisentraut)
The SQL standard allows this behavior, and because of the primary key, the result is unambiguous.
要使其在早期版本的 PostgreSQL 下工作,请将选择列表中不使用聚合函数的所有表达式添加到 GROUP BY 子句。
关于hibernate - 使用 JPA 和 PostgreSQL 9.0 分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10091178/