我有一个实体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'
   }
}

一些不相​​关的注释:

您不应在idequals计算中使用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/

10-11 06:26