可以使用 Grails derived 属性 来检索域对象吗?
Possible to use Grails derived property to retrieve domain object?
我有域 classes 用于 Request
、RequestSet
(单个用户同时提交的个人请求的集合)和请求 Status
.我想汇总请求的状态,以便请求集的状态由其各个请求的状态决定。
这些域 classes 的相关部分如下所示:
class RequestSet {
Long id
static hasMany = [requests: Request]
}
class Request {
Long id
Status status
}
class Status {
Long id
String status
}
我尝试将派生的 status
属性 添加到 RequestSet
class 中,如下所示:
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 的瞬态 属性,但我希望能够使用动态查找器根据它们的冒泡状态检索请求集。我见过的所有示例都按原样使用公式的结果;我想知道我是否能以某种方式让 Grails 将返回值解释为 Status
class.
的 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 看起来像这样:
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 之前?
在回答我最初的问题时,不,您不能使用公式推导出属于另一个域 class 的 属性。我无数次失败的尝试使我得出了这个结论,this blog 的作者似乎也这么认为。具体来说,"derived properties can be of any type supported by Hibernate" 和我的 Status
class 不是。
至于我的后续问题,根据 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 日志记录。这真的有助于弄清楚发生了什么。
我有域 classes 用于 Request
、RequestSet
(单个用户同时提交的个人请求的集合)和请求 Status
.我想汇总请求的状态,以便请求集的状态由其各个请求的状态决定。
这些域 classes 的相关部分如下所示:
class RequestSet {
Long id
static hasMany = [requests: Request]
}
class Request {
Long id
Status status
}
class Status {
Long id
String status
}
我尝试将派生的 status
属性 添加到 RequestSet
class 中,如下所示:
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 的瞬态 属性,但我希望能够使用动态查找器根据它们的冒泡状态检索请求集。我见过的所有示例都按原样使用公式的结果;我想知道我是否能以某种方式让 Grails 将返回值解释为 Status
class.
编辑,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 看起来像这样:
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 之前?
在回答我最初的问题时,不,您不能使用公式推导出属于另一个域 class 的 属性。我无数次失败的尝试使我得出了这个结论,this blog 的作者似乎也这么认为。具体来说,"derived properties can be of any type supported by Hibernate" 和我的 Status
class 不是。
至于我的后续问题,根据 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 日志记录。这真的有助于弄清楚发生了什么。