派生 属性 调用存储函数抛出 StreamCorruptedException

Derived property calling stored function throws StreamCorruptedException

我试图通过用派生字段替换动态字段(没有底层数据库表示的瞬态 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))'
}

问题是,现在当我 运行 any 查询域时,即使像 Request.list() 这样简单,我也会收到以下异常:

Class: java.io.StreamCorruptedException
消息:无效流header:32303135

为了额外的乐趣,这是一个抽象域 class。我不知道这是否真的有什么不同;它仍然像任何其他域一样保存在数据库中,我正在调用抽象 class 本身的查询,而不是实现。

最令人沮丧的是派生字段本身确实有效!我可以使用它成功检索客户名称;就是查询不到整体域名。

最后,我非常有信心派生 属性 是问题所在,因为我已将其注释掉,然后可以成功查询域。

如果以后有人遇到这个问题,问题实际上 摘要 class。不仅因为它是一个抽象的 class——它还是一个抽象的 领域 class。显然,Grails 不支持这些属性的派生属性。

要将查询移动到数据库,我只需要开始将已解析的客户端保存到我的请求域中:/