Grails createCriteria并使用Transient字段和PagedResultsList

时间:2014-08-21 22:08:42

标签: hibernate grails transient createcriteria

域名字段:

startDate: Date
length: Integer
perpetuity: Boolean
expiryDate: Transient (startDate + length (in years))

域方法 - 这些方法用于过滤大型过滤器表单,以便用户搜索4种不同的过期状态。

Date getExpiryDate() {
    if (this.startDate == null || this.length == null) {
        return null
    }

    Timestamp startDate = this.startDate;
    Calendar expirationDate = Calendar.getInstance()
    expirationDate.setTime(startDate)
    expirationDate.add(Calendar.YEAR, this.length)

    return expirationDate.getTime()
}

String getMechExpiredStatus() {
    String isExpiredString = 'Unspecified'
    Date expDate = getExpiryDate()
    if (expDate != null) {
        if (expDate < new Date()) {
            isExpiredString = 'Yes'
        } else {
            isExpiredString =  'No'
        }

    } else if (isPerpetual && startDate != null) {
        isExpiredString =  'Perpetual'
    }

    return isExpiredString
}

构建结果列表

PagedResultList getMechanisms(offset, max, sortColumn, sortOrder, filters, idsOnly = false) {
    def criteria = Mechanism.createCriteria()
    def results = criteria.list(max: max, offset: offset) {
        if (idsOnly) {
            projections {
                property('id')
            }
        }

        if (filters && filters.idFilter) {
            eq('id', filters.idFilter);
        }
    ...
    }

    if (filters && filters.expiredFilter != null && filters.expiredFilter) {
        // Do Work
        // Tried getting results and removed invalid results that do not meet the 
        // expired filter selection
    }

return results

}

我似乎找不到使用瞬态字段'expiryDate'编写createCriteria的方法,也没有使用getMechExpiredStatus方法。

我尝试使用其他过滤器获取项目列表,然后单独删除对过期过滤器无效的项目,但PagedResultList未正确更新;它只返回当前的分页结果列表。我也找不到关于PagedResultList对象的帮助。由于某种原因,Remove和Add返回一个布尔值。显然我不太了解这个对象。

如果我从初始条件列表中删除了max和offset,则查询需要非常长时间才能运行。

我有什么想法可以做到这一点?

2 个答案:

答案 0 :(得分:1)

您无法查询瞬态属性。根据定义,瞬态属性不存在于数据源中,因此不能成为数据源执行的查询的一部分。

为了使用瞬态属性完成您要做的事情,您需要创建自己的结果列表,而不使用数据源提供的限制和偏移功能,过滤结果,然后应用偏移和限制自己。

由于您还未提供查询内容的示例,因此我将自己编写一个示例:

// this could be any type of query, using list for simplicity of the example
def databasePersons = Person.list()
// assumes anAdult is a boolean transient property of person
// calculated based on age
def filteredPersons = databasePersons.findAll{ it.isAnAdult() }

// get rid of the first X records, the offset
filteredPersons = filteredPersons.drop(offset)

// only take the next X remaining records, the max
filteredPersons = filteredPersons.take(max)

答案 1 :(得分:1)

我通过在视图中创建过期状态和日期并将其链接到域对象来解决问题。效果很棒!