apache / apache/grails-core

Creating (without executing) a detached Criteria (with a .where{..}) can cause `select count(*)` queries to run

Open
#14,425 1 comment 0 reactions 0 assignees View on GitHub
relates-to: grails-data-hibernate5
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

### Task List

- [x] Steps to reproduce provided
- [NA] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)

### Steps to Reproduce

1. create a where query that joins in a related class:

2. Don't execute the where query.

```
@Entity
class Pet {
static hasMany = [nickNames: NickName]
String name
}

@Entity
class NickName {
static belongsTo = [pet: Pet]
String nickname
}

def query = Pet.where {
def tags = nickNames
tags.nickname == "Spot"
order("tags.nickname")
}
```

### Expected Behaviour

No sql statements should be executed.

### Actual Behaviour

A `count(*)` query is executed on the relationship table.
`select count(*) as y0_ from nick_name this_ limit ?`

### Environment Information

- **Operating System**: windows
- **GORM Version:** 7.0.8
- **Grails Version (if using Grails):** 4.0.10
- **JDK Version:** 8

### Example Application

https://github.com/tircnf/ExtraQuery

The only source code in the project is the following hibernateSpec which requires that sql logging be enabled in logback.groovy.

```
logger 'org.hibernate.SQL', DEBUG
```

```
import grails.persistence.Entity
import grails.test.hibernate.HibernateSpec
import org.junit.Rule
import org.springframework.boot.test.rule.OutputCapture

class ExtraQuerySpec extends HibernateSpec {

@Rule
OutputCapture capture = new OutputCapture()

@Override
List getDomainClasses() {
return [Pet, NickName]
}

void testSetup() {
expect:
true
!capture.toString()
}

void testLogging() {
expect:
new Pet(name: "jerry").save(flush: true, failOnError: true)
capture.toString().contains("insert into pet")
}

void testCriteria() {
when: "I create a detachedCriteria"
Pet.where {

}
then: "no query is executed"
!capture.toString()
}

void "test and query join criteria."() {
when: "I create query with join and projection"
Pet.where {
def tags = nickNames
tags.nickname == "Spot"

order("tags.nickname")

}

then: "No query should have been executed, but count(*) from nick_name runs."
!capture.toString()
}
}

@Entity
class Pet {

static hasMany = [nickNames: NickName]
String name

}

@Entity
class NickName {
static belongsTo = [pet: Pet]
String nickname
}
```

Contributor guide

Open the contributing guide

Research direction

Start with the ExtraQuerySpec reproduction using HibernateSpec, Pet.where, and the joined nickNames relationship, with SQL logging enabled in logback.groovy. Trace detached Criteria creation to identify why the unexecuted query triggers a count(*) statement; done means creating the joined where query produces no SQL.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.