1
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 ($1)
    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通用的,但据我了解,可以为映射定义任意返回类型,并且它可以在其他存储库中使用。


我正在使用带有spring-boot-starter-data-r2dbcand的 spring-boot 2.5.1 io.r2dbc:r2dbc-postgresql。其他存储库按预期工作。

4

1 回答 1

1

事实证明,使用蛇盒而不是骆驼盒可以正常工作:

SELECT task_id, AVG(rating) as avg_rating, COUNT(*) as reviews_count
FROM task_review
WHERE task_id IN (:taskIds)
GROUP BY task_id

因为不支持在选定列的别名中使用驼峰式大小写是出乎意料的,所以我在这里提出了一个问题来跟进好春天的人:https ://github.com/spring-projects/spring-data-r2dbc/问题/616

于 2021-07-01T07:25:20.827 回答