I am using grails 2.5.3
I have a config like:
grails {
hibernate {
cache.queries = true
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.SingletonEhCacheProvider'
I have domain class like:
class AuthorizedDevice implements JSONFormat {
int id
String authKey = generateAuthKey()
String owner
String name
String permittedUsers
String userAgent
Date lastVisit
Date lastInitialized
String lastUser
String lastIpAddress
Date dateCreated
boolean enabled = true
String notes
static constraints = {
authKey(blank: false, unique: true, maxSize: 8)
owner(blank: false, validator: GormValidators.isCorpUserName)
name(blank: false, unique: 'owner')
permittedUsers(nullable: true, validator: permittedUsersValidator)
userAgent(nullable: true, maxSize: 500)
lastVisit(nullable: true)
lastInitialized(nullable: true)
lastUser(nullable: true, maxSize: 50)
lastIpAddress(nullable: true, maxSize: 50)
notes(nullable: true, maxSize: 500)
}
def auditService
def afterInsert() {auditService.noteDeviceChange('Created Device', id)}
def afterUpdate() {auditService.noteDeviceChange('Updated Device', id)}
def afterDelete() {auditService.noteDeviceChange('Deleted Device', null)} // Not allowed by GUI, but just in case.
public Object formatForJSON() {
return [
id: id,
authKey: authKey,
owner: owner,
name: name,
permittedUsers: permittedUsers,
userAgent: userAgent,
lastVisit: lastVisit,
lastInitialized: lastInitialized,
lastUser: lastUser,
lastIpAddress: lastIpAddress,
enabled: enabled,
notes: notes
]
}
//------------------
// Implementation
//------------------
private String generateAuthKey() {
....
}
static permittedUsersValidator = {String val, Object obj, Errors errors ->
if (!val || val.trim().equals('*')) return
val.split(',').each {
if (!getCorprUser(it.trim())) {
errors.rejectValue('permittedUsers', '',
"Unknown User ${it}. Use a comma-delimited list of usernames or * to indicate all users."
)
}
}
}
}
I build a device list like:
def devices = AuthorizedDevice.list()
I notice that GORM/hibernate is doing one SQL query for every row in the table every time AuthorizedDevice.list() is called.
We do not have any associations in the model fields that would generate N+1 queries.
Does someone know what prompts this N+1 like behaviour even though there are no associations?
The first time the .list() is called, the following SQL is run just once:
select
this_.id as id4_0_,
this_.version as version4_0_,
this_.auth_key as auth3_4_0_,
this_.date_created as date4_4_0_,
this_.enabled as enabled4_0_,
this_.last_initialized as last6_4_0_,
this_.last_ip_address as last7_4_0_,
this_.last_user as last8_4_0_,
this_.last_visit as last9_4_0_,
this_.name as name4_0_,
this_.notes as notes4_0_,
this_.owner as owner4_0_,
this_.permitted_users as permitted13_4_0_,
this_.user_agent as user14_4_0_
from
authorized_device this_
Everytime the .list() is called thereafter, this SQL gets run for every row in the table:
select
authorized0_.id as id4_0_,
authorized0_.version as version4_0_,
authorized0_.auth_key as auth3_4_0_,
authorized0_.date_created as date4_4_0_,
authorized0_.enabled as enabled4_0_,
authorized0_.last_initialized as last6_4_0_,
authorized0_.last_ip_address as last7_4_0_,
authorized0_.last_user as last8_4_0_,
authorized0_.last_visit as last9_4_0_,
authorized0_.name as name4_0_,
authorized0_.notes as notes4_0_,
authorized0_.owner as owner4_0_,
authorized0_.permitted_users as permitted13_4_0_,
authorized0_.user_agent as user14_4_0_
from
authorized_device authorized0_
where
authorized0_.id=?