Я работаю над проектом, включающим Spring
и JPA/Hibernate
. Драйвер базы данных, используемый в моей среде разработки, H2
. В моем приложении есть страница, на которой отображается статистика, одним из примеров такой статистики является средний возраст моих пользователей. Однако, когда я пытаюсь получить средний возраст, используя JPQL
, я получаю исключение
Result must not be null!
Для простоты предположим, что я храню возраст как integer
для каждого User
объекта (в моем приложении это, конечно, не так, но это не важно для моей проблемы).
Модель пользователя
@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, но это не очень эффективно.
StackTrace:
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();