无法在 Hibernate where-criteria 中使用 rowCount()

Unable to use rowCount() in Hibernate where-criteria

我正在尝试使用 Hibernate 在 Grails 中创建一个简单的查询。我想 return 每个状态中的元素数量。 sql 中的查询如下所示:

select status, count(*) from UDTRAEKDATA
where UDTRAEK_JOB_ID='41'
group by status;

产生以下 table

STATUS COUNT(*)
FAERDIG 12023
FEJL 434

域class定义如下:

class Udtraekdata {

    String jsonData
    UdtraekdataStatus status
    UdtraekEntitetType entitetType
    Date lastUpdated
    int antalLaasNulstillinger

    static hasOne = [udtraekdatafil: Udtraekdatafil, udtraekJob: UdtraekJob]

    static constraints = {
        udtraekdatafil nullable: true
        jsonData nullable: true
        faerdigbehandlet nullable: true
    }

    static mapping = {
        status index: 'idx_udtraekdata'
        udtraekJob index: 'idx_udtraekdata'
        udtraekdatafil index: 'Udtraekdata_fil_idx'
        id generator: 'sequence', params:[sequence: 'udtraekdata_sequence']
    }

}

我相信我应该能够像这样在 Hibernate 中创建相应的查询(在此处完成 f.ex。grails 3.3 gorm where query with projection count() different than list().size()):

    Udtraekdata.where {
            udtraekJob.jobId == "job1"

            projections {
                groupProperty 'status'
                rowCount()
            }
        }.list()

然而,这会导致 GroovyCastException 消息:

"Cannot cast object '10' with class 'java.lang.Integer' to class 'java.util.List'"

我错过了什么?我想懒惰地执行此操作,因为会有数百万行,我不想将它们提取到内存中。

我终于找到了我的错误。显然,Spock 或 Grails 在单元测试中一直存在 Hibernate 问题,并且被迫使用集成测试。在单元测试中计算行数时,这似乎仍然是一个问题(即使我使用的是 Grails 4)。因此,对我来说,解决方案只是设置一个集成测试。

我最后的服务方式:

UdtraekStatusInfo hentUdtraekStatus(Long udtraekId) {
        Map<UdtraekdataStatus, Integer> statusMap = Udtraekdata.where {
            udtraekJob.id == udtraekId

            projections {
                groupProperty "status"
                rowCount()
            }
        }.list().collectEntries { row ->
            return [row[0], row[1]]
        }

        return new UdtraekStatusInfo(udtraekId, statusMap)
    }

我的期末考试class:

@Integration
@Rollback
class UdtraekStatusServiceIntSpec extends Specification {

    UdtraekStatusService udtraekStatusService

    def "hentUdtraekStatus"() {
        given:
            UdtraekJob job1 = DomainTestHelper.getUdtraekJob().save(flush: true)
            UdtraekJob job2 = DomainTestHelper.getUdtraekJob().save(flush: true)

            [job1, job2].each { job ->
                UdtraekdataStatus.values().eachWithIndex { status, index ->
                    (0..index).each {
                        DomainTestHelper.getCompleteUdtraekData(udtraekJob: job, status: status).save(flush: true)
                    }
                }
            }
        when:
            UdtraekStatusInfo info = udtraekStatusService.hentUdtraekStatus(job1.id)
        then:
            UdtraekJob.count == 2
            Udtraekdata.count == 30
            // More test statements...
    }
}