findAll order by "many to one" 列引发异常

findAll order by "many to one" column raises exception

我有一个实体 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 在某些情况下失败或 returns 意外结果。

所以第一个查询是

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'
   }
}

一些不相关的笔记:

您不应在 equalshashCode 计算中使用 id;如果您有一个持久性 Student 和一个具有相同名称、类型和大学的新非持久性实例,则应将它们视为相等,但由于非持久性实例的 id 将为空,因此它们将被视为不同.

您不需要指定 id 属性 - Grails 在编译期间通过 AST 转换将它和 version 字段添加到字节码。

无需将 university 属性 的列名称映射到 'UNIVERSITY_ID' - 反正就是这样。

您可以在 id 映射中省略多余的 column 设置。

这是删除了废话的学生 class:

@EqualsAndHashCode(includes = ['name', 'type', 'university'])
class Student {
   String name
   String type
   University university
}

和大学:

class University {
   String name
   static mapping = {
      id generator: 'assigned'
   }
}