0

我看到一些奇怪的行为,我认为这些行为与 GORM 缓存有关,但我不知道如何解决这个问题。我有一个项目对象,其中包含一个 purchaseOrderEntries 列表,每个都有一个开始日期。如果用户在采购订单状态日期中输入两位数年份,我将其转换为 4 位数年份,然后对日期进行排序。但他们没有正确排序!这是重要的片段:

def updatePurchaseOrderEntryDates(def project) {
   def poEntryList = project.purchaseOrderEntries
   poEntryList?.each { DateHelper.updateTwoDigitYear(it?.startDate) }  // 2-digit yr

   poEntryList?.sort()
   log.info "list 1: " + poEntryList
   poEntryList?.sort()
   log.info "list 2: " + poEntryList

输出以下内容:

list 1: 1965, 2020, null
list 2: 2020, 1965, null

第二次调用相同的排序方法怎么会产生不同的结果?我错过了什么?我觉得这是一个休眠延迟加载或缓存或其他问题。没有线索。有任何想法吗?

*更新W/更多信息* 感谢所有的想法。不幸的是,解决方案似乎并不那么容易。排序工作正常,只是似乎每次都有效。这就是为什么它似乎是一个我不太了解的问题。项目对象包含一个采购订单条目列表 - 这是一个列表(不是一组),并且 PurchaseOrderEntry 对象实现了 Comparable。这是代码:

class Project ... {

    static hasMany = [purchaseOrderEntries:ProjectPurchaseOrderEntry, ...]

    static mapping = {
        purchaseOrderEntries cascade:'all-delete-orphan'
        ...
    }

    List<ProjectPurchaseOrderEntry> purchaseOrderEntries
    ...
}


class ProjectPurchaseOrderEntry ... implements Comparable {

    Project project
    Date startDate
    Date endDate

    ...

    int compareTo(obj) {
        // Compare these dates in reverse older. i.e. put the newest/earliest date on the top and the oldest/null date at the end of the list
        return obj.startDate <=> startDate     // this comparison is done in reverse - comparator operator is null safe
    }

    ... 

}

换句话说,排序似乎工作正常。问题在这里

  poEntryList?.each { DateHelper.updateTwoDigitYear(it?.startDate) }  // 2-digit yr   
  poEntryList?.sort()

即使列表中的所有日期都更新为 4 位数的年份,它仍然会排序,就好像这些日期没有更新一样。我怀疑 2 位数的年份是儒略历日期,4 位数的年份是公历日期,并且我的比较运算符默默地失败了。但是......为什么日期没有更新,因为它们在之前的每个循环中?那是我没有得到的。是否每个人都在执行 SQL 查询以延迟获取 project.purchaseOrderEntries,然后再次使用它(而不是新排序的列表)?即使我将排序结果保存在一个新列表中,例如:

    poEntryList?.each { DateHelper.updateTwoDigitYear(it?.startDate) }  // support two digit year entry
    def sortedList = poEntryList?.sort({it?.startDate})?.reverse()

新的“sortedList”仍然没有正确排序。我认为这可能的唯一方法是,如果它没有使用更新的日期进行排序。再次感谢您的所有帮助。欢迎任何想法。这个快把我逼疯了。

4

4 回答 4

1

Hibernate 默认不提供任何排序​​顺序。所以我假设它工作正常,而你的 sort() 方法什么也不做。您应该提供排序顺序,如下所示:

def sortedList = poEntryList?.sort { it.startDate }
于 2012-12-04T10:43:01.267 回答
0

Grails 中的hasMany关系使用数据类型Set。一个集合没有按设计排序,所以不告诉它按什么排序,它什么也不做。

更新您的帖子后更新。

1)List<ProjectPurchaseOrderEntry> purchaseOrderEntries可以简化为List purchaseOrderEntries

2) A.each{ .. }不返回集合。它只是一个循环。如果您希望.collect{..}数组中的项目由闭包中的代码更新,则需要。

3) AhasMany类型List不打算实现 Comparable,因此不需要覆盖。它按元素添加到列表中的顺序排序。

4)一旦你做了一个.collect{ .. }你不再有你的域对象的列表,因此你设置的任何排序都不会被使用。我的意见是使用标准的 Set 数据类型,然后收集,然后说.sort{it.startDate}.reverse()

于 2012-12-04T22:06:23.900 回答
0

Groovy-JDKCollection.sort()方法仅在调用它的集合是List. 因为hasMany关系是Set默认的

poEntryList.sort()

保持poEntryList不变并按排序顺序返回一个 List的(这里的“排序”是指根据compareTo集合中对象的顺序)。如果您记录List返回的sort()集合而不是原始集合,您应该以一致的排序顺序看到它(当然假设对象具有有意义的compareTo方法)。

于 2012-12-04T22:50:15.187 回答
0

这个问题困扰了我好几次。检查返回类型 - 它可能是一个 Set。您需要转换为 ArrayList 然后排序。尝试以下操作:

def sortedList = poEntryList?.toArray().sort { it.startDate } 
于 2015-07-29T20:47:20.577 回答