{"id":4453,"date":"2011-11-01T11:28:55","date_gmt":"2011-11-01T05:58:55","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=4453"},"modified":"2016-11-30T13:06:46","modified_gmt":"2016-11-30T07:36:46","slug":"criteria-query-with-left-outer-join","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/criteria-query-with-left-outer-join\/","title":{"rendered":"Criteria Query with Left Outer Join"},"content":{"rendered":"<p>In <a title=\"grails development services\" href=\"http:\/\/www.tothenew.com\/grails-application-development\">Grails app development<\/a>, when using criteria queries, we often find cases for Outer joins. Lets take an example. We have two domain classes with us:<\/p>\n<p>[java]<br \/>\nclass Blog {<\/p>\n<p>\tString title<br \/>\n\tString content<\/p>\n<p>\tstatic hasMany = [comments: Comment]<\/p>\n<p>    static constraints = {<br \/>\n    }<br \/>\n}<br \/>\n[\/java]<\/p>\n<p>and<\/p>\n<p>[java]<br \/>\nclass Comment {<\/p>\n<p>\tString text<\/p>\n<p>\tstatic belongsTo = [blog: Blog]<\/p>\n<p>    static constraints = {<br \/>\n    }<br \/>\n}<br \/>\n[\/java]<\/p>\n<p>Now, lets say, we want get the title of all the blogs along with the count of the comments on it. The query that we try is:<\/p>\n<p>[java]<br \/>\nList blogStats = Blog.createCriteria().list {<br \/>\n\t\tcreateAlias(&#8216;comments&#8217;, &#8216;c&#8217;)<br \/>\n            \tprojections {<br \/>\n                \tgroupProperty(&#8216;id&#8217;)<br \/>\n                \tgroupProperty(&#8216;title&#8217;)<br \/>\n\t\t\tcount(&#8216;c.id&#8217;)<br \/>\n            }<br \/>\n}<br \/>\n[\/java]<\/p>\n<p>Interestingly, we do not get what we want. We do get a list of list of id, title and comments count, but only for those blogs for which comments exist. So, with creating an alias, we just created a join but what we need is a left outer. As always, stackoverflow had the <a href=\"http:\/\/stackoverflow.com\/questions\/7154364\/how-do-i-make-a-grails-criteria-execute-as-a-left-join\">answer<\/a>. The createAlias method can take another parameter to specify that we want the join to be a Left outer join.<\/p>\n<p>We&#8217;ll need to add the following import:<\/p>\n<p>[java]import org.hibernate.criterion.CriteriaSpecification[\/java]<\/p>\n<p>And the our query looks like:<\/p>\n<p>[java]<br \/>\nList blogStats = Blog.createCriteria().list {<br \/>\n      createAlias(&#8216;comments&#8217;, &#8216;c&#8217;, CriteriaSpecification.LEFT_JOIN)<br \/>\n      projections {<br \/>\n\t\t         groupProperty(&#8216;id&#8217;)<br \/>\n                \tgroupProperty(&#8216;title&#8217;)<br \/>\n         \t\tcount(&#8216;c.id&#8217;)<br \/>\n      }<br \/>\n}<br \/>\n[\/java]<\/p>\n<p>Looks pretty simple now that I know it \ud83d\ude42 How about you? Hope it helps.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Grails app development, when using criteria queries, we often find cases for Outer joins. Lets take an example. We have two domain classes with us: [java] class Blog { String title String content static hasMany = [comments: Comment] static constraints = { } } [\/java] and [java] class Comment { String text static belongsTo [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":48},"categories":[7],"tags":[4840,4005,4264],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/4453"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=4453"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/4453\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=4453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=4453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=4453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}