hibernate - 无法访问 hql namedQuery 中的独立域对象

标签 hibernate grails hql named-query

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

一些背景:
我有一个 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 验证的产品集成,并且我无法控制产品的 native 域模型。我们添加了一个独立的自定义 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 无法处理的。

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

最佳答案

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

  • JobOrder,更具体地说是底层 JOBORDER 表和填充该表的机制,是第 3 方产品。你也不能改变。
  • JOBORDER 中的行可能包含 ZIP 表中不存在的 PUBLISHEDZIP 值。
  • 您当前的 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 才能做到这一点,我不确定这种方法与命名查询的效果如何。

    关于hibernate - 无法访问 hql namedQuery 中的独立域对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5006044/

    相关文章:

    javascript - 如何将 JavaScript 变量传递给 Groovy Controller ?

    从表中检索记录时,Hibernate异常: org. hibernate.hql.internal.ast.QuerySyntaxException

    nhibernate - 在 Hibernate HQL 更新查询中使用连接

    java - 仅选择 HQL 中链接实体中列的子集

    hibernate 环境 : Delete Data from _AUD table using native query

    java - Hibernate 刷新和 JTAUnexpectedRollbackException

    templates - Groovy/Grails SimpleTemplateEngine卡住

    Hibernate:ManytoOne - 有多少个对象?

    Hibernate 5.1 与 Postgis 2.2 几何列映射

    mongodb - MongoDB身份验证无法在Grails中运行,但可以通过控制台进行