hibernate - 优化:渴望获取基域类实例

标签 hibernate grails gorm query-performance grails-2.3

Grails应用程序维护有关已保存文档的数据。

使用名为Document的基本域类为域类创建简单的域类层次结构。

当前使用每个子类的表方法。它不是最有效的,但是现在还可以。

对文档的访问由ACL控制,该ACL与另一个域类一起建模。

在一种特定情况下,无论实例类型如何(在顶层),一堆分配给一个ACL的文档都必须分配给另一个ACL。

ACL渴望获取已声明批次以优化阅读文档的文档。

class Document {
}

class Image extends Document {
}

class ACL {
  Collection documents
  static mapping = {
     documents   lazy: false, batchSize: 100
  }

}

启用急切的访存并不能改善性能。

已启用SQL日志记录以分析问题。我发现文档记录已按预期获取,但是对于每个文档,使用for循环进行迭代时,会对文档集合中的每个元素执行带有子类表的附加联接查询。
ACL original = ACL.get(id)
for (doc in original.documents) {
  // Do whatever needs to be done
}

我假设触发了此行为,因为doc没有使用显式类型。我尝试了这个:
ACL original = ACL.get(id)
for (Document doc : original.documents) {
  // Do whatever needs to be done
}

不幸的是,它没有帮助。

有没有办法告诉Grails它不会因为不必要而不会从表中获取子类的数据:将只使用基类?

最佳答案

不,没有办法告诉Hibernate(实际上是在这样做,而不是在Grails上)做到这一点。如果您需要这种类型的优化,则需要使用原始SQL,而不是基于HQL或GORM的查询。

要解释为什么不可能这样做,您需要从ORM Angular 考虑这一点。在您的网域示例中,此处未显示“文档”,而是“图像”。具体实例始终是“图像”实例,而不是“文档”实例。为了合并文档列表,ORM不仅必须加载基类中的数据,还必须加载实现类中的数据。这是无法避免的。避免这种情况将创建不是该域的有效表示形式的类的实例。

这是使用ORM必须支付的价格之一。

关于hibernate - 优化:渴望获取基域类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25886488/

相关文章:

mysql - 指定不同的主机以使用grails进行读写

grails - 如何停止在终端上获取调试消息?

grails - GORM在删除时多对一关系中将外键设置为null

grails - 无法删除GORM中的用户

mysql - SQL查询按结果分组

caching - Grails message.properties 更改未在部署的应用程序中生效

java - 如何在 REST 架构中使用 Spring 和 Jackson 只请求必要的字段?

hibernate - org.hibernate.StaleObjectStateException:行已由另一个事务更新或删除(或未保存的值映射不正确)

spring - java.lang.IllegalArgumentException : Unknown entity 异常

database - 使用 JPA、Hibernate 的 PostgreSQL 继承