有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重构闭包标准用于固定列表中表达式的最大数量为1000

我在一个需要维护的应用程序中发现了以下代码

 def addCriteriaClosure = { criteriaList ->
   criteriaList.inList('id', paketInstance.dateien.id)
 }
 def criteria = Datei.createCriteria()
 def result = criteria.list() {
   addCriteriaClosure.call(criteria)
 }

遗憾的是,此调用导致以下错误:

java.sql.SQLSyntaxErrorException: ORA-01795: maximum number of expressions in a list is 1000

事实是paketInstance.dateien包含超过1000行/项。 为了避免此错误,我尝试了以下方法:

def addCriteriaClosure = { criteriaList ->
  paketInstance.dateien.asList().collate(999).each {
    criteriaList.inList('id', paketInstance.dateien.asList().collate(999).id)
  }
}

但这会导致以下错误:

java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.Long

我知道解决方案是使用collate(999)操作,但我不知道如何将其与初始方法结合起来以获得预期的结果

编辑#1

不幸的是,我无法编辑实现的这一部分:

 def criteria = [Type].createCriteria()
 def result = criteria.list() {
   addCriteriaClosure.call(criteria)
 }

其中,具体类型被传递给方法。 我只能编辑addCriteriaClosure的定义 例如:

 def addCriteriaClosure = { criteriaList ->
   criteriaList.inList('id', paketInstance.dateien.id)
 }

编辑#2

当我设计我的标准闭包时,如下所示

def l = paketInstance.dateien.id.toList().collate(999)
        def addCriteriaClosure = { criteriaList ->

            l.each {
                a -> criteriaList.inList("id", a.toList())
            }
        }

Hibernate创建一个SQL语句,将列表拆分为inWHERE子句。但问题是这两个子句与AND关联。为了得到正确的结果,我需要两个列表的OR,而不是生成的sql中的AND

生成的SQL:

 select this_.id as id51_0_, this_.version as version51_0_, this_.aktualisiert_am as aktualis3_51_0_, this_.name as name51_0_, this_.nummer as nummer51_0_, this_.pfad as pfad51_0_, this_.status as status51_0_, this_.typ as typ51_0_ from datei this_ where this_.id in (?, ?, ?, ?, ?, ?....)  and this_.id in (?, ?, ?, ?, ?, ?, ?....)

因此,我需要的不是and this_.id中的or this_.id in


共 (3) 个答案

  1. # 1 楼答案

    找到了解决办法

    def collatedFileList = paketInstance.dateien.id.toList().collate(999)
            def addCriteriaClosure = { criteriaList ->
                criteriaList.or {
                    collatedFileList.each {
                        l -> criteriaList.inList("id", l.toList())
                    }
                }
            }
    
    1. 解决了我不得不面对的问题
    2. 了解了很多关于关闭/标准的事情
  2. # 2 楼答案

    如果要将ID列表限制为不超过999项,则应使用

    def idList = paketInstance.dateien.asList().id[0..<999]
    

    旁白

    仅仅因为Oracle不允许一个in谓词中的项超过1000项,就丢弃一些要比较的ID似乎不是一个好的解决方案。假设此ID列表是从数据库检索的,那么您应该能够使用子查询/联接来执行比较

  3. # 3 楼答案

    请尝试以下方法:

    def manyThingsToFind = [...list of more than 1000 things...]
    def clauseLimit = 999
    def results = YourDomainObject.createCriteria().listDistinct {
      or {
        manyThingsToFind.collate(clauseLimit)?.each { collatedList ->
          'in'("fieldToMatch", collatedList)
        }
      }
    }
    

    您可以根据需要将实际条件分解为一个闭包,就像您已经做的那样