【问题标题】:Can't access a stand alone domain object in hql namedQuery无法访问 hql namedQuery 中的独立域对象
【发布时间】:2011-06-27 17:20:32
【问题描述】:

首先我需要为这篇冗长的帖子道歉,我在为过于冗长但又不够清晰而苦恼。我还为我的问题广泛搜索了一个优雅的解决方案,如果我错过了,请指导我。

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

我将从当前关注的 namedQuery 开始:

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

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

def openJobs = JobOrder.openAdJobs

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

  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 列表,因此有一个非常令人反感的 hack 来获取我的结果集。我需要获取一个已知良好的 JobOrder(或创建一个),以便可以调用 getOpenAdJobsSql() 方法。

类似:

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

需要在我当前调用 openAdJobs 命名查询的任何地方添加(目前有 9 种或更多用法)。甚至考虑这种方法都会给我发出心理警告,但我看不出有其他方法可以添加附加功能。

同样,最终我希望调用命名查询,但附加的邮政编码 sql 似乎是 GORM + hibernate 无法处理的。

我希望有人会知道一个更优雅的解决方案。并且请在本文中遗漏的任何地方要求澄清。

【问题讨论】:

  • 抱歉,1) 将getOpenAdJobsSql() 设为静态有什么问题? 2)是说有非空adLocation-s 不在Zip 中,是您需要过滤掉的那些?如果您尝试在命名查询中添加 notNull('adLocation') 会怎样?
  • 让 getOpenAdJobsSql() 成为静态作品,这对我来说是一个新手疏忽。感谢您和 proflux。

标签: hibernate grails hql named-query


【解决方案1】:

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

  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 才能做到这一点,我不确定这种方法与命名查询的效果如何。

【讨论】:

  • 我最喜欢 inList 方法,并将继续研究它作为解决方案,但我遇到了将 Zip 转换为正确类型的问题。但最终,将方法设置为静态会获胜。感谢您为我保释……虽然我还不能投票,但我还是得到了答复。
  • 很高兴为您提供帮助。您可能想尝试:inList 'adLocation', Zip.list().collect{it.id}
猜你喜欢
  • 2011-06-24
  • 2013-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-23
相关资源
最近更新 更多