无法在 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...
}
}
我正在尝试使用 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...
}
}