无法访问 hqlnamedQuery 中的独立域对象

发布于 2024-10-17 21:36:51 字数 3238 浏览 4 评论 0原文

首先,我需要为这么长的帖子道歉,我为过于冗长而又不够清晰而苦苦挣扎。我还广泛搜索了针对我的问题的优雅解决方案,如果我错过了它,请指导我。

一些背景:
我有一个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
}

I 的域模型将从当前相关的命名查询开始:

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

该查询存在于我的 JobOrder 域对象中,该对象也与 AdCategory 域对象有关系。使用以下调用在多个位置调用命名查询:

def openJobs = JobOrder.openAdJobs

我的新问题:
现在我需要确保我不会发布任何具有无效邮政编码的职位。我正在与不包含 zip 验证的产品集成,并且我无法控制该产品的本机域模型。我们添加了一个独立的自定义 Zip 域对象。我一直在努力寻找一种方法来包含与 JobOrder 对象中的命名查询一起使用的代码,以完成以下查询将返回的内容:(我在 dbvisualizer 中针对 sql 数据库运行此查询)

  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  
  ) 

< strong>一个不太漂亮的解决方案:
我和几个同行获得所需结果集的唯一方法是在我的 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,否则该方法不可用。因为此时我实际上正在尝试构建我的工作订单列表,所以有一个非常令人倒胃口的黑客来获取我的结果集。我需要获取一个已知的良好 JobOrder(或创建一个),以便可以调用 getOpenAdJobsSql() 方法。

类似这样的内容:

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

需要在我当前调用 openAdJobs 命名查询的任何地方添加(当前有 9 种或更多用途)。即使考虑这种方法也会给我带来精神上的警告,但我认为没有其他方法可以添加附加功能。

再说一次,最终我希望调用命名查询,但额外的邮政编码 sql 似乎是 GORM + hibernate 无法处理的。

我希望有人知道更优雅的解决方案。并请在这篇文章中遗漏的任何地方要求澄清。

First I need to apologize for the long post, I struggle with being overly verbose and yet not always clear enough. I also have searched extensively for an elegant solution for my issue and if I missed it please direct me to it.

Some Background:
I have a grails app that is using namedQueries for a set of standard result sets. The app finds open advertised Job Orders in our system and sends them to other sites. Recently an additional requirement has become a problem for me if I wish to continue using the namedQueries.

For the sake of simplicity let's just assume a domain model of

    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
}

I will begin with the current namedQuery in concern:

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

This query exists in my JobOrder domain object which also has a relationship with the AdCategory domain object. The named query is called in multiple places using the following call:

def openJobs = JobOrder.openAdJobs

My New Problem:
Now I have a requirement to make sure I don't publish any jobs that have invalid zip codes. I am integrating with a product which contains no zip validation and I have no control over the product's native domain model. We have added a custom Zip domain object that is stand alone. I have struggled figuring out a way to include code that will work with the named query in my JobOrder object to accomplish what the following query would return: (i run this query against the sql db in 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  
  ) 

A not-so-pretty solution:
The only way I and a couple of peers have gotten the desired result set is by creating a method like the following in my JobOrder object:

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)
}  

The method, of course, is not available unless I instantiate a JobOrder. Since I am actually attempting to build my list of JobOrders at this point there is a very unappetizing hack to get my result set. I would need to fetch a known good JobOrder (or create one) so the getOpenAdJobsSql() method is available to call.

something like:

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

would need to be added everywhere I currently call the openAdJobs named query (currently 9 or more usages). To even consider this approach is sending mental warning flares up for me, but I see no other way to add the additional feature.

Again, ultimately it is my desire to call a named query, but the additional zip code sql appears to be something GORM + hibernate is not going to be able to handle.

It is my hope that someone will know of a more elegant solution. And please ask for clarity anywhere it is missing in this post.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

摇划花蜜的午后 2024-10-24 21:36:52

好的,如果我理解您的问题:

  1. JobOrder,更具体地说是底层 JOBORDER 表和填充该表的机制,是第 3 方产品。你也无法改变。
  2. JOBORDER 中的行可能包含 ZIP 表中不存在的 PUBLISHEDZIP 值。
  3. 您当前的 GORM 模型不包含 JOBORDER 和 ZIP 之间的关系,因此您无法使用 Criteria/HQL 来选择仅包含有效邮政编码的数据子集。

可能有效的选项:

  • 将您描述的方法设置为静态,这样您就不需要实例化底层类的对象。
  • 对您的命名查询使用 inList 限制(我还没有测试过这一点,但似乎它应该有效)。

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

我认为可能有一个性能更好的替代方案,您可以使用涉及使用 Exists 子句替换 inList 的子查询表达式,但我不确定 CriteriaBuilder/GORM Criteria 是否支持这一点。您可能必须进入 Hibernate 才能执行此操作,并且我不确定该方法与命名查询的配合效果如何。

Okay, so if I understand your problem:

  1. JobOrder, more specifically the underlying JOBORDER table and the mechanism to populate that table, is a 3rd party product. You cannot change either.
  2. Rows in JOBORDER may contain PUBLISHEDZIP values which do not exist in your ZIP table.
  3. Your current GORM model does not contain a relationship between JOBORDER and ZIP so you therefore cannot use a Criteria/HQL to select a subset of the data that contains only valid ZIP codes.

Options that might work:

  • make the method you described static so you don't need to instantiate an object of the underlying class.
  • use the inList restriction on your named query (I haven't tested this, but seems like it should work).

.

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

I think there is probably a better performing alternative that you could use involving a Subquery expression that replaces the inList with an Exists clause, but off the top of my head I'm not sure if CriteriaBuilder/GORM Criteria supports that or not. You might have to get down into the Hibernate to do that and I'm not sure how well that approach plays with named queries.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文