一尘不染

使用GORM / Hibernate轻松加载查询

hibernate

我的Grails应用程序具有以下域对象

class ProductType {
    String name
    static hasMany = [attributes: Attribute]
}

class Attribute {       
    String name
    static belongsTo = [productType: ProductType]
}

我的数据库有7 ProductTypes,每个都有3 Attributes。如果执行查询:

def results = ProductType.withCriteria {
    fetchMode("attributes", org.hibernate.FetchMode.EAGER)
}

我预计ProductType将返回7个实例,但实际上我得到21个(7 x 3)。我知道如果我要执行与上述相同的SQL查询,则结果集将有21行

prod1 | attr1
prod1 | attr2
prod1 | attr3
..... | .....
..... | .....
prod7 | attr1
prod7 | attr2
prod7 | attr3
-------------
Total 21

但是我认为当我通过Hibernate / GORM检索这些结果时,我应该会得到更多类似的信息:

prod1 | attr1, attr2, attr3    
..... | ...................
..... | ...................
prod7 | attr1, attr2, attr3
---------------------------
Total 7

顺便说一句,如果我从上面的查询中删除了eager-loading,我得到ProductType的期望值为7 s。我想念什么?


阅读 269

收藏
2020-06-20

共1个答案

一尘不染

您应该阅读以下常见问题解答:对于为集合启用了外部联接获取的查询,Hibernate不会返回不同的结果(即使我使用了distinct关键字)?

如您注意到的那样,当您指定急切加载时,结果集包含7 * 3行,但实际上您的内存中只有7个productTypes对象(每个对象有2个额外的引用)。
要执行您想要的操作,您可以添加(请注意基础sql查询未更改):

SetResultTransformer(new DistinctRootEntityResultTransformer())

def results = ProductType.withCriteria {
    fetchMode("attributes", org.hibernate.FetchMode.EAGER)
    SetResultTransformer(new DistinctRootEntityResultTransformer())
}
2020-06-20