Pie*_*rcq 6 java spring h2 spring-data spring-data-jpa
我正在做一个涉及Spring和的项目JPA/Hibernate。我的开发环境中使用的数据库驱动程序是H2. 我的应用程序有一个显示统计信息的页面,此类统计信息的一个示例是我的用户的平均年龄。但是,当我尝试使用 获取平均年龄时JPQL,我收到一个异常
Result must not be null!
Run Code Online (Sandbox Code Playgroud)
为简单起见,假设我将年龄存储为integer每个User对象的一个(在我的应用程序中这当然不是这种情况,但这对我的问题并不重要)。
用户模型
@Entity
public class User implements Identifiable<Long> {
private int age;
// more fields and methods, irrelevant
}
Run Code Online (Sandbox Code Playgroud)
用户存储库
@Repository
public interface UserRepository extends CrudRepository<User, Long> {
@Query("SELECT AVG(u.age) FROM #{#entityName} u")
long averageAge();
}
Run Code Online (Sandbox Code Playgroud)
我似乎无法弄清楚为什么调用UserRepository#averageAge();会引发异常。我已尝试将AVG查询中的函数替换为by ,COUNT并且其行为符合预期。我也尝试nativeQuery = true在注释中使用 SQL 查询和设置,但无济于事。我当然可以通过获取所有用户并用普通 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
Run Code Online (Sandbox Code Playgroud)
解决了
该异常是由在空表上执行时AVG()返回的事实引起的null。我通过修改查询(受到这个问题的答案的启发)来修复它,如下所示:
@Query("SELECT coalesce(AVG(u.age), 0) FROM #{#entityName} u")
long averageAge();
Run Code Online (Sandbox Code Playgroud)
如果您使用 Spring Data,并且如果您的方法null在 Hibernate 找不到匹配项时返回,请确保添加@org.springframework.lang.Nullable到您的方法签名中:
public interface SomeRepositoryCustom {
@org.springframework.lang.Nullable
public Thing findOneThingByAttr(Attribute attr) {
/* ...your logic here... */
}
}
Run Code Online (Sandbox Code Playgroud)
这是因为 Spring Data 会检查您的方法的可空性,如果缺少注释,它将强制您始终需要返回一个对象:
public interface SomeRepositoryCustom {
@org.springframework.lang.Nullable
public Thing findOneThingByAttr(Attribute attr) {
/* ...your logic here... */
}
}
Run Code Online (Sandbox Code Playgroud)
我使用了 Spring Boot 版本2.1.1.RELEASE和 Spring Data 2.1.4.RELEASE。
| 归档时间: |
|
| 查看次数: |
3034 次 |
| 最近记录: |