我正在处理一个涉及
假设为了简化,我在每个用户对象上将年龄存储为整数(在我的应用程序中当然不是这种情况,但这对我的问题并不重要)。
用户模型
我似乎找不出为什么调用
Spring
和JPA/Hibernate
的项目。在我的开发环境中使用的数据库驱动程序是H2
。我的应用程序有一个显示统计信息的页面,其中一个例子是用户的平均年龄。然而,当我尝试使用JPQL
获取平均年龄时,我收到了一个异常。Result must not be null!
假设为了简化,我在每个用户对象上将年龄存储为整数(在我的应用程序中当然不是这种情况,但这对我的问题并不重要)。
用户模型
@Entity
public class User implements Identifiable<Long> {
private int age;
// more fields and methods, irrelevant
}
用户存储库
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
@Query("SELECT AVG(u.age) FROM #{#entityName} u")
long averageAge();
}
我似乎找不出为什么调用
UserRepository#averageAge();
会抛出异常。 我尝试将查询中的函数AVG
替换为COUNT
,并且这行为符合预期。 我还尝试使用SQL查询并在注释中设置nativeQuery = true
,但无济于事。 当然,我可以通过获取所有用户并在普通Java中计算平均年龄来解决此问题,但这并不是很有效。
堆栈跟踪:
Caused by: org.springframework.dao.EmptyResultDataAccessException: Result must not be null!
at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:102)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy150.averageAge(Unknown Source)
at my.test.application.StatisticsRunner.run(StatisticsRunner.java:72)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:809)
... 30 more
已解决
异常是由于在空表上执行AVG()
会返回null
引起的。我通过修改查询语句(灵感来源于这个问题的答案)来解决这个问题:
@Query("SELECT coalesce(AVG(u.age), 0) FROM #{#entityName} u")
long averageAge();