Wednesday, August 22, 2018

Grails on Groovy > Way in Grails to Eager Fetch the Whole Record | Load Related Entity With Single Query

I am trying to find if there is any way in Grails to eager fetch complete records instead of a left Join.
For example, let you have domain named Tabel1 with following structure and another domain named Table3 below:
package com.pkm

class Table1 {
    Long id
    String name
    String roll

    static mapping = {
        table("table1")
    }

    static belongsTo = [
            table3: Table3
    ]

    static constraints = {
        table3 nullable: true
    }
}



package com.pkm

class Table3 {
    Long id
    String name
}
So when you get/list Table1, what will be the default behavior? It will load only Table1 data, not other associated data like Table3.
There is a procedure to load selected associated by joining them. See the below example, enabled eager face data when creating criteria:
package com.pkm

import grails.transaction.Transactional
import org.hibernate.FetchMode
import org.hibernate.sql.JoinType
import org.springframework.transaction.TransactionStatus

@Transactional
class HomeService {
    TransactionStatus transactionStatus

    void callMe() {
        List list = Table1.createCriteria().list {
            createCriteria("table3", "j3", JoinType.LEFT_OUTER_JOIN)
            setFetchMode("j3", FetchMode.JOIN)
            order("id", "desc")
            setMaxResults(20)
        }
        list.each { Table1 table1 ->
            println("Name=${table1.name}, Table3=${table1.table3?.name}")
        }
    }
}
Now we will print the query generated:
select this_.id as id1_0_1_, this_.name as name2_0_1_, this_.roll as roll3_0_1_, this_.table3_id as table4_0_1_, j3x1_.id as id1_2_0_, j3x1_.name as name2_2_0_ from table1 this_ left outer join table3 j3x1_ on this_.table3_id=j3x1_.id order by this_.id desc limit ?
You observed that in select query, both Table1 and Table3 exists. And this is how we can implement eager face data when creating criteria builder to get data.

No comments:

Post a Comment