我正在尝试通过用派生字段替换动态字段(没有底层数据库表示的瞬态getter)来提高性能,以便我可以使用例如Criteria来查询我的模型。原始动态字段非常简单:
Client resolveClient() {
if (prevCall && prevCall.client) {
return prevCall.client
} else {
return client
}
}
我不知道如何用一个MySQL语句重现它,所以我想我会继续把它放到一个存储函数中,定义如下:
CREATE FUNCTION `request_client`(requestId long) RETURNS varchar(255) CHARSET utf8
begin
declare pci long;
declare clientId long;
declare clientName varchar(255);
select request.prev_call_id
from request
where request.id = requestId
into pci;
if pci is not null then
select call_history.client_id
from call_history
where call_history.call_id = pci
into clientId;
else
select request.client_id
from request
where request.id = requestId
into clientId;
end if;
select clients.client_name
from clients
where clients.client_id = clientId
into clientName;
return clientName;
end;
然后我在派生字段中调用该函数:
String derivedFieldName
static mapping = {
derivedFieldName formula: '(select stored_function(id))'
}
现在的问题是,当我在域上运行任何查询时,即使像Request.list()
一样简单,我也会遇到以下异常:
类: java.io.StreamCorruptedException
消息:无效的流标题:32303135
为了额外的乐趣,这是一个抽象的域类。我不知道这是否真的有所不同;它仍然像任何其他域一样持久化到数据库,我在抽象类本身上调用查询,而不是实现。
最令人沮丧的是派生字段本身确实有效!我可以使用它成功检索客户名称;我只是无法查询整个域名。
最后,我非常确信派生属性是问题所在,因为我已将其评论出来,然后可以成功查询域。
答案 0 :(得分:0)
如果有人稍后遇到此问题,实际上的问题是抽象类。而且不只是它是一个抽象类 - 它是一个抽象的域类。显然,Grails不支持那些派生属性。
要将查询移动到数据库,我只需要开始将已解析的客户端保存到我的请求域中:/