Не удается получить доступ к отдельному объекту домена в hql namedQuery - PullRequest
1 голос
/ 15 февраля 2011

Сначала я должен извиниться за длинный пост, я борюсь с тем, чтобы быть слишком многословным и все же не всегда достаточно ясным. Я также активно искал элегантное решение для моей проблемы, и если я пропустил его, пожалуйста, направьте меня к нему.

Некоторая справка:
У меня есть приложение Grails, которое использует namedQueries для набора стандартных наборов результатов. Приложение находит открытые рекламные заказы в нашей системе и отправляет их на другие сайты. В последнее время дополнительные требования стали для меня проблемой, если я хочу продолжать использовать namedQueries.

Для простоты, давайте просто предположим, что модель домена

    class JobOrder {

  def getOpenAdJobsSql() {
    def qry = "select jo FROM JobOrder jo WHERE isOpen=1 AND publishedTo='All External' AND adCategory.isActive=1 AND jo.adLocation in (select zc.id from Zip zc)"

    JobOrder.executeQuery(qry)

  }

  static namedQueries = {

    openAdJobs {
      eq 'isOpen', true
      eq 'publishedTo', "All External"
      adCategory {
        eq 'isActive', true
      }
    }

  static mapping = {
    table 'dbo.JOBORDER'
    version false
    id generator: 'identity', column: 'JOBORDERID'
    isOpen column: 'ISOPEN'
    publishedTo column: 'customText15'
    adLocation column: 'PUBLISHEDZIP'
    adCategory column: 'customInt3'
  }

  Boolean isOpen
  String publishedTo
  String adLocation
  ClientCorporation client
  AdCategory adCategory

  static constraints = {
    adLocation(size: 0..100)
  }

}

    class AdCategory {    
  static mapping = {
    table 'dbo.AdCategory'
    version false
    id generator: 'identity', column: 'adCategory_ID'
    isActive column: 'active'
  }
}

    class Zip {
    static mapping = {
        table 'ZIP'
        version false
        id generator: 'identity', column: 'ZIPCODE'
        city  column: 'city'
        county  column: 'county'
        stateAbbr column: 'statecode'
    }

    String city
    String county
    String stateAbbr
}

Я начну с текущего именованного вопроса:

openAdJobs {
  eq 'isOpen', true
  eq 'publishedTo', "All External"
  adCategory {
    eq 'isActive', true
  }
}

Этот запрос существует в моем объекте домена JobOrder, который также связан с объектом домена AdCategory. Именованный запрос вызывается в нескольких местах с использованием следующего вызова:

def openJobs = JobOrder.openAdJobs

Моя новая проблема:
Теперь у меня есть требование, чтобы я не публиковал работы, которые имеют недопустимые почтовые индексы. Я интегрируюсь с продуктом, который не содержит проверки по почтовому индексу, и у меня нет контроля над собственной моделью домена продукта. Мы добавили собственный объект домена Zip, который является отдельным. Я изо всех сил пытался найти способ включить код, который будет работать с именованным запросом, в мой объект JobOrder, чтобы выполнить то, что должен вернуть следующий запрос: (я запускаю этот запрос для базы данных sql в dbvisualizer)

  select * from dbo.JobOrder jo  
  inner join dbo.AdCategory ac on jo.adCategory=ac.adCategory_ID  
  where  
  jo.isOpen=1  
  and  
  jo.publishedTo='All External'  
  and  
  ac.isActive=1  
  and  
  jo.publishedZip in (  
        select zc.zipcode from dbo.Zip zc  
  ) 

Не очень красивое решение:
Единственный способ, которым я и пара коллег получили желаемый набор результатов, - это создание метода, подобного следующему, в моем объекте JobOrder:

def getOpenAdJobsSql() {
    def qry = "select jo FROM JobOrder jo WHERE isOpen=1 AND publishedTo='All External' AND adCategory.isActive=1 AND jo.adLocation in (select zc.id from Zip zc)"

    JobOrder.executeQuery(qry)
}  

Метод, конечно, недоступен, если я не создаю экземпляр JobOrder. Поскольку на данный момент я пытаюсь составить свой список JobOrders, существует очень неаппетитный хак, чтобы получить набор результатов. Мне нужно получить известный хороший JobOrder (или создать его), чтобы метод getOpenAdJobsSql () был доступен для вызова.

что-то вроде:

def jo = JobOrder.get(2)
def rset = jo.openAdJobsSql

необходимо будет добавлять везде, где я в настоящее время называю openAdJobs именованным запросом (в настоящее время 9 или более случаев использования). Даже подумать о том, что такой подход вызывает у меня всплески умственного предупреждения, но я не вижу другого способа добавить дополнительную функцию.

Опять же, в конечном счете, я хочу вызвать именованный запрос, но дополнительный почтовый индекс sql кажется чем-то, что GORM + hibernate не сможет обработать.

Я надеюсь, что кто-то узнает о более элегантном решении. И, пожалуйста, попросите ясности в любом месте, где оно отсутствует в этом посте.

1 Ответ

0 голосов
/ 15 февраля 2011

Хорошо, так что, если я понимаю вашу проблему:

  1. JobOrder, более конкретно базовая таблица JOBORDER и механизм для заполнения этой таблицы, является сторонним продуктом.Вы также не можете изменить.
  2. Строки в JOBORDER могут содержать значения PUBLISHEDZIP, которых нет в вашей таблице ZIP.
  3. Ваша текущая модель GORM не содержит отношения между JOBORDER и ZIP, поэтому вы не можетеиспользуйте Criteria / HQL для выбора подмножества данных, которое содержит только допустимые почтовые индексы.

Параметры, которые могут работать:

  • делают метод, который вы описали, статическим, чтобы вы моглине нужно создавать экземпляр объекта базового класса.
  • использовать ограничение inList для вашего именованного запроса (я не проверял это, но, похоже, он должен работать).

.

openAdJobs {
    eq 'isOpen', true
    eq 'publishedTo', "All External"
    inList 'adLocation', Zip.list()
    adCategory {
      eq 'isActive', true
   }
 }

Я думаю, что, возможно, есть более эффективная альтернатива, которую вы могли бы использовать, включив выражение Subquery, которое заменяет inList предложением Exists, но не в моей голове, я не уверенесли CriteriaBuilder / GORM Criteria поддерживает это или нет.Возможно, вам придется войти в Hibernate, и я не уверен, насколько хорошо этот подход работает с именованными запросами.

...