我有一个实体Student,在Student.groovy中定义为:
@EqualsAndHashCode(includes = ['id'])
class Student {
Long id
String name
String type
University university
static mapping = {
university column : 'UNIVERSITY_ID'
}
}
一个大学实体,在University.groovy中定义为:
class University {
Long id
String name
static mapping = {
id column : 'id', generator : 'assigned'
}
}
我一直在尝试从通话中切换
Student.list(sort: ..., order: ...)
致电:
Student.findAll("from Student s where type = :type ", [type : 'T'], [ sort : 'name' ])
无法按名称字段正确排序。使用
list
的先前版本运行良好。我也试过打电话
Student.findAll(sort : 'name') { type == "T" }
像这样工作正常,但是当尝试按university.name排序时
Student.findAll(sort : 'university.name') { type == 'T" }
它引发了有关找不到university.name字段的错误。
有人对如何正确执行此操作有任何想法吗?
谢谢。
最佳答案
使用executeQuery
而不是findAll
-它们应该具有相同的功能,但是我发现executeQuery
出于某种原因是HQL的更直接调用者,并且findAll
失败或在某些情况下返回意外结果。
所以第一个查询是
Student.executeQuery(
'select s from Student s where s.type = :type order by s.name',
[type : 'T'])
并按大学名称排序
Student.executeQuery(
'select s from Student s where s.type = :type order by s.university.name',
[type : 'T'])
我喜欢HQL并且倾向于使用它很多,但是它使您与Hibernate和关系数据库联系在一起-如果要切换到NoSQL数据库,这些查询将失败。标准查询,“where”查询和查找器都在内部使用标准查询,并且GORM实现将这些标准查询转换为本地查询API调用。
等效条件查询为
Student.withCriteria {
eq 'type', 'T'
order 'name', 'asc'
}
和
Student.withCriteria {
eq 'type', 'T'
university {
order 'name', 'desc'
}
}
一些不相关的注释:
您不应在
id
或equals
计算中使用hashCode
;如果您有一个持久Student
和一个具有相同名称,类型和大学的新非持久实例,则应将它们视为相等,但是由于非持久实例的ID将为null,因此将它们视为不同的。您不需要指定
id
属性-Grails会在编译过程中通过AST转换将其和version
字段添加到字节码中。无需将
university
属性的列名称映射到'UNIVERSITY_ID'-就是这样。您可以在
column
映射中省略多余的id
设置。这是删除了粗体的学生类:
@EqualsAndHashCode(includes = ['name', 'type', 'university'])
class Student {
String name
String type
University university
}
和大学:
class University {
String name
static mapping = {
id generator: 'assigned'
}
}
关于grails - “many to one”列的findAll顺序引发异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27776118/