首页 > 解决方案 > 使用 JPQL 时出现 Spring JPA 存储库转换错误

问题描述

我声明了一个 PagingAndSorting JPA 存储库。我正在使用@Query 注释。

当我从存储库的 findById(id) 方法调用 Optional 对象的 get() 方法时遇到异常。

奇怪的是它只发生在我使用 JPQL 时。

如果我的查询是本机的,则该代码有效:

    @Override
public BatchDto findById(String id) {
    Optional<Batch> findResult =  this.batchRepository.findById(id);
    if (!findResult.isPresent()) return null;
    Batch entity = findResult.get();  **<-------- Cast Exception Here**
    BatchDto dto = this.mapper.toDto(entity, BatchDto.class);
    List<BatchTransaction> transactions = entity.getTransactions();
    dto.setTransactionDtos(mapper.toListDto(transactions, TransactionDto.class));
    return dto;
}

用断点检查findResult对象 - 我可以看到:

Optional[net.domain.data.batch@4b8bb6f] 

当我在 @Query 注释中有 nativeQuery = true 时。

@Query(value = Sql.FindBatchById, nativeQuery = true) 

这是正在使用的查询:

SELECT DISTINCT(B.batchNumber), COUNT(B.batchNumber) as TransactionCount FROM BATCH B WHERE B.batchReferenceNumber = :id GROUP BY B.batchNumber

但是,如果我将其更改为 JPQL 并删除 nativeQuery=true 属性 - findResult 是

Optional[[Ljava.lang.Object;@76e04327].  

我得到一个 ClassCastException:

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to net.domain.data.batch

所以底线 - 这在指定 nativeQuery=true 时有效,并且在我尝试使用 JPQL 时失败。

我不想指定 nativeQuery,因为我们最终会将这个数据库移植到 Oracle。

标签: jpaspring-data

解决方案


首先,下面显示的查询不返回单个Batch实例。由于有distinctcount聚合函数,查询将返回 a Listof 聚合。为了能够读取该统计信息,您可以将适当的方法添加到 batchRepository。像这样的东西:

@Query("SELECT DISTINCT(B.batchNumber) as dist, COUNT(B.batchNumber) as cnt FROM BATCH B GROUP BY B.batchNumber")
  List<Map<Long, Long>> findStatistics();

然后遍历列表。

UPD

如果 id 参数完全保证将返回单个记录,则可以将返回类型更改为Map

@Query("SELECT DISTINCT(B.batchNumber) as dist, COUNT(B.batchNumber) as cnt FROM BATCH B WHERE B.batchReferenceNumber = :id GROUP BY B.batchNumber")
      Map<Long, Long> findStatisticsById(@Param("id") Long id);

推荐阅读