Search code examples
grailsgrails-ormgrails-2.0

Grails/Gorm - namedQuery hasMany relationship


I have the following domain classes

class EventA {
   static belongsTo = [offer: Offer]
}
class EventB extends EventA {}
class EventC extends EventA {}

class Offer {
 static hasMany [events: EventA]
} 

I need to retrieve offers that are not associated with an EventC.

In SQL this can easily be performed as:

SELECT *
  FROM OFFER O
  LEFT JOIN EVENTC C ON O.event_id = C.id
 WHERE C.ID IS NULL

Searching through the grails documentation I found instanceOf. Stating that once you have the result set you can perform a check of the instance type.

    def offers = Offer.list()
    for (Offer o in offers) {
       for(Event e : o.events) {
          if (e.instanceOf(EventC)) {
              // no bueno
          }
       }
    }

The above just feels wrong. I would prefer to have the database do such filtering for me. Is there a way to perform such a filter with searchCriteria?


Solution

  • This actually ended up being easier then I expected. On my search criteria, I can build an expression to not include any Offer that has an event EventC.

    Example:

    Offer.with {
       events {
         ne('class', EventC)
       }
    }
    

    Since I questioned this approach I enabled hibernate logging. Ironically, it generated SQL that was pretty similar to what I was after.

    SELECT *
      FROM OFFER O
      LEFT JOIN EVENTB B ON O.ID == B.EVENT_ID
      LEFT JOIN EVENTC C ON O.ID == C.EVENT_ID
     WHERE
     (
      CASE 
          WHEN B.ID IS NOT NULL THEN 1
          WHEN C.ID IS NOT NULL THEN 2
        END <> ?
      )