为什么查询结果映射为 COUNT(*) 为空值?
Why is the query result mapped with a null value for COUNT(*)?
interface TaskReviewRepository : CoroutineCrudRepository<TaskReview, Long> {
@Query(
"""
SELECT task_id, AVG(rating) as avgRating, COUNT(*) as reviewsCount
FROM task_review
WHERE task_id IN (:taskIds)
GROUP BY task_id
"""
)
fun ratingSummaryWhereTaskIdIn(taskIds: Set<Long>): Flow<TaskReviewService.RatingSummaryWithTaskId>
}
data class RatingSummaryWithTaskId(
val taskId: Long,
val avgRating: Double?,
val reviewsCount: Long,
)
当我在数据库中手动运行这个查询时
SELECT task_id, AVG(rating) as avgRating, COUNT(*) as reviewsCount
FROM task_review
WHERE task_id IN (1)
GROUP BY task_id
结果是:
task_id | avgRating | reviewsCount
1 | 5.00000 | 1
但是当我使用来自服务的存储库时,我得到:
2021-06-30 09:22:33.240 DEBUG 7529 --- [ parallel-3] io.r2dbc.postgresql.PARAM : Bind parameter [0] to: 1
2021-06-30 09:22:33.246 DEBUG 7529 --- [ parallel-3] io.r2dbc.postgresql.QUERY : Executing query:
SELECT task_id, AVG(rating) as avgRating, COUNT(*) as reviewsCount
FROM task_review
WHERE task_id IN ()
GROUP BY task_id
// ...
org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.example.tasks.TaskReviewService$RatingSummaryWithTaskId using constructor fun <init>(kotlin.Long, kotlin.Double?, kotlin.Long): com.example.tasks.TaskReviewService.RatingSummaryWithTaskId with arguments 1,null,null
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:246) ~[spring-data-commons-2.5.1.jar:2.5.1]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
// ...
Caused by: java.lang.IllegalArgumentException: Parameter reviewsCount must not be null!
为什么映射器使用 null 作为第三个参数?
(com.example.tasks.TaskReviewService.RatingSummaryWithTaskId with arguments 1,null,null
)
我的猜测是存储库本身使用 TaskReview
而不是 RatingSummaryWithTaskId
作为泛型,但据我所知,可以为映射定义任意 return 类型,并且它适用于其他存储库。
我正在使用 spring-boot 2.5.1 与 spring-boot-starter-data-r2dbc
和 io.r2dbc:r2dbc-postgresql
。其他存储库按预期工作。
事实证明使用蛇形外壳而不是驼峰外壳效果很好:
SELECT task_id, AVG(rating) as avg_rating, COUNT(*) as reviews_count
FROM task_review
WHERE task_id IN (:taskIds)
GROUP BY task_id
因为不支持在选定列的别名中使用驼峰式大小写是意想不到的,所以我在这里提出了一个问题来跟进 spring 好人:https://github.com/spring-projects/spring-data-r2dbc/issues/616
interface TaskReviewRepository : CoroutineCrudRepository<TaskReview, Long> {
@Query(
"""
SELECT task_id, AVG(rating) as avgRating, COUNT(*) as reviewsCount
FROM task_review
WHERE task_id IN (:taskIds)
GROUP BY task_id
"""
)
fun ratingSummaryWhereTaskIdIn(taskIds: Set<Long>): Flow<TaskReviewService.RatingSummaryWithTaskId>
}
data class RatingSummaryWithTaskId(
val taskId: Long,
val avgRating: Double?,
val reviewsCount: Long,
)
当我在数据库中手动运行这个查询时
SELECT task_id, AVG(rating) as avgRating, COUNT(*) as reviewsCount
FROM task_review
WHERE task_id IN (1)
GROUP BY task_id
结果是:
task_id | avgRating | reviewsCount
1 | 5.00000 | 1
但是当我使用来自服务的存储库时,我得到:
2021-06-30 09:22:33.240 DEBUG 7529 --- [ parallel-3] io.r2dbc.postgresql.PARAM : Bind parameter [0] to: 1
2021-06-30 09:22:33.246 DEBUG 7529 --- [ parallel-3] io.r2dbc.postgresql.QUERY : Executing query:
SELECT task_id, AVG(rating) as avgRating, COUNT(*) as reviewsCount
FROM task_review
WHERE task_id IN ()
GROUP BY task_id
// ...
org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate com.example.tasks.TaskReviewService$RatingSummaryWithTaskId using constructor fun <init>(kotlin.Long, kotlin.Double?, kotlin.Long): com.example.tasks.TaskReviewService.RatingSummaryWithTaskId with arguments 1,null,null
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:246) ~[spring-data-commons-2.5.1.jar:2.5.1]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
// ...
Caused by: java.lang.IllegalArgumentException: Parameter reviewsCount must not be null!
为什么映射器使用 null 作为第三个参数?
(com.example.tasks.TaskReviewService.RatingSummaryWithTaskId with arguments 1,null,null
)
我的猜测是存储库本身使用 TaskReview
而不是 RatingSummaryWithTaskId
作为泛型,但据我所知,可以为映射定义任意 return 类型,并且它适用于其他存储库。
我正在使用 spring-boot 2.5.1 与 spring-boot-starter-data-r2dbc
和 io.r2dbc:r2dbc-postgresql
。其他存储库按预期工作。
事实证明使用蛇形外壳而不是驼峰外壳效果很好:
SELECT task_id, AVG(rating) as avg_rating, COUNT(*) as reviews_count
FROM task_review
WHERE task_id IN (:taskIds)
GROUP BY task_id
因为不支持在选定列的别名中使用驼峰式大小写是意想不到的,所以我在这里提出了一个问题来跟进 spring 好人:https://github.com/spring-projects/spring-data-r2dbc/issues/616