Grails 3 - return list in query result from HQL query

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-13 07:00:55

问题


I have a domain object:

class Business {
    String name
    List subUnits

    static hasMany = [
            subUnits : SubUnit,
    ]
}

I want to get name and subUnits using HQL, but I get an error

Exception: org.springframework.orm.hibernate4.HibernateQueryException: not an entity

when using:

List businesses = Business.executeQuery("select business.name, business.subUnits from Business as business")

Is there a way I can get subUnits returned in the result query result as a List using HQL? When I use a left join, the query result is a flattened List that duplicates name. The actual query is more complicated - this is a simplified version, so I can't just use Business.list().


回答1:


I thought I should add it as an answer, since I been doing this sort of thing for a while and a lot of knowledge that I can share with others:

As per suggestion from Yariash above:

This is forward walking through a domain object vs grabbing info as a flat list (map). There is expense involved when having an entire object then asking it to loop through and return many relations vs having it all in one contained list

@anonymous1 that sounds correct with left join - you can take a look at 'group by name' added to end of your query. Alternatively when you have all the results you can use businesses.groupBy{it.name} (this is a cool groovy feature} take a look at the output of the groupBy to understand what it has done to the

But If you are attempting to grab the entire object and map it back then actually the cost is still very hefty and is probably as costly as the suggestion by Yariash and possibly worse.

List businesses = Business.executeQuery("select new map(business.name as name, su.field1 as field1, su.field2 as field2) from Business b left join b.subUnits su ")

The above is really what you should be trying to do, left joining then grabbing each of the inner elements of the hasMany as part of your over all map you are returning within that list.

then when you have your results

def groupedBusinesses=businesses.groupBy{it.name} where name was the main object from the main class that has the hasMany relation.

If you then look at you will see each name has its own list

groupedBusinesses: [name1: [ [field1,field2,field3], [field1,field2,field3] ]

you can now do

groupedBusinesses.get(name) to get entire list for that hasMany relation.

Enable SQL logging for above hql query then compare it to

List businesses = Business.executeQuery("select new map(b.name as name, su as subUnits) from Business b left join b.subUnits su ")

What you will see is that the 2nd query will generate huge SQL queries to get the data since it attempts to map entire entry per row.

I have tested this theory and it always tends to be around an entire page full of query if not maybe multiple pages of SQL query created from within HQL compared to a few lines of query created by first example.



来源:https://stackoverflow.com/questions/38363404/grails-3-return-list-in-query-result-from-hql-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!