【问题标题】:Possible to use Grails derived property to retrieve domain object?可以使用 Grails 派生属性来检索域对象吗?
【发布时间】:2016-12-06 23:41:19
【问题描述】:

我有 RequestRequestSet(单个用户同时提交的单个请求的集合)和请求 Status 的域类。我想汇总请求的状态,以便请求集的状态由其各个请求的状态确定。

这些领域类的相关部分如下所示:

class RequestSet {
    Long id
    static hasMany = [requests: Request]
}

class Request {
    Long id
    Status status
}

class Status {
    Long id
    String status
}

我尝试将派生的status 属性添加到RequestSet 类,如下所示:

class RequestSet {
    Long id
    Status status
    static hasMany = [requests: Request]

    static transients = ['status']

    static mapping = {
        status formula: '(SELECT MIN(status_id) FROM (SELECT status_id FROM request rq WHERE rq.request_set_id = id))'
    }
}

但是,当我运行我的应用并检查 requestSet 对象的属性时,状态都是空的。

我正在尝试使用派生属性来实现吗?我可以使用 getter 来满足瞬态属性,但我希望能够使用动态查找器根据它们的冒泡状态检索 requestSet。我见过的所有示例都按原样使用公式的结果;我想知道是否可以让 Grails 将返回的值解释为 Status 类的 ID。

编辑,2016 年 12 月 7 日:请注意,我将派生的 status 属性标记为瞬态。如果不这样做,我会从 Hibernate 获得ClassCastException

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'transactionManager_companion' while setting constructor argument with key [1]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager_companion': Cannot resolve reference to bean 'sessionFactory_companion' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory_companion': Invocation of init method failed; nested exception is java.lang.ClassCastException: org.hibernate.mapping.Formula cannot be cast to org.hibernate.mapping.Column
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

我怀疑即使公式有效,我也无法使用具有此属性的动态查找器,因为它被标记为瞬态。我将满足于使用公式来计算状态的 id,但我仍然遇到问题。

现在我的域类看起来像这样:

class RequestSet {
    Long id
    Long statusId
    static hasMany = [requests: Request]

    static mapping = {
        statusId formula: '(SELECT MIN(status_id) FROM (SELECT rq.status_id FROM request rq WHERE rq.request_set_id = id))'
    }
}

获取请求集时公式生成的SQL为

(SELECT MIN(this_.status_id) FROM (SELECT rq.status_id FROM request rq WHERE rq.request_set_id = this_.id)) as formula3_0_ from request_set

我得到一个SQLSyntaxErrorException:ORA-00904: "THIS_"."STATUS_ID": invalid identifier。我怎样才能重写公式,以便“this_.”没有添加到 status_id 之前?

【问题讨论】:

    标签: grails grails-orm


    【解决方案1】:

    在回答我最初的问题时,不,您不能使用公式来派生属于另一个域类的属性。我无数次失败的尝试使我得出了这个结论,this blog 的作者似乎也这么认为。具体来说,“派生属性可以是 Hibernate 支持的任何类型”,而我的 Status 类不是。

    至于我的后续问题,根据this answer for a different question,HQL 不支持我使用的公式。我设法使用此公式将statusId 作为派生属性:

    (SELECT MIN(status.id) FROM status WHERE status.id IN (SELECT rq.status_id FROM request rq WHERE rq.request_set_id = id))
    

    感谢@Mike 建议打开 SQL 日志记录。这确实有助于弄清楚发生了什么。

    【讨论】:

      猜你喜欢
      • 2015-12-20
      • 1970-01-01
      • 2013-10-27
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      • 2012-04-02
      • 2011-09-14
      • 2011-03-05
      相关资源
      最近更新 更多