Показать сообщение отдельно
Старый 22.03.2016, 10:41   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
2,925 / 1540 (57) ++++++++
Регистрация: 12.10.2004
? Опасный orig
Привет всем.

Хочу обсудить особенность работы метода orig.
Суть в том что при создании записи из клиентского кода, при передаче буфера на сервер, common.orig() начинает возвращать тот же буфер, что может приводить к неприятным глюкам. Очевидно это баг/фича при репликации буферов между клиентом и сервером.
Понимаю, что описано немного сумбурно, поэтому во вложении пример.

Буфер заполняем в джобе GRD_TestOrig (джоб работает на клиенте).
Далее при исполнении на клиенте все ок, orig() возвращает пустой буфер, но при переходе исполнения на сервер (например внутри метода Insert() который всегда на сервере исполняется), orig() начинает возвращать непустой буфер равный текущему.

Из-за этого могут некорректно работать модификации закладывающиеся на сравнение значений полей в буфере с его orig() значениями.

В стандарте похоже эту багофичу учитывали, поэтому и написан такой код:

\Classes\InventUpd_Estimated\initUpdate
X++:
//AOSRunMode::Server
void initUpdate()
{
...
movement_Orig = movement.newMovement_Orig();
...
}
\Classes\InventMovement\newMovement_Orig
X++:
InventMovement newMovement_Orig()
{
    InventMovement movement_orig;

    if (this.buffer().RecId)
    {
        if (this.childBuffer().RecId)
            movement_orig = InventMovement::construct(this.buffer().orig(),this.inventMovSubType(),this.childBuffer().orig());
        else
            movement_orig = InventMovement::construct(this.buffer().orig(),this.inventMovSubType());
    }

    return movement_orig; // по факту пустой буфер принудительно возвращен а не orig()
}

\Classes\InventMov_Sales\newMovement_Orig
X++:
InventMovement newMovement_Orig()
{
    if (salesOrderLine.RecId)
        return new InventMov_Sales(salesOrderLine.orig());
    else
        return null; // а здесь не заморачивались, а просто вернули null вместо orig()
}

Вопросы такие :
1. Интересно, почему так сделано в ядре? Баг, который стал фичей или для чего-то нужно ?
2. Как это можно быстро исправить для кучи модификаций без переделки кода ?
(к сожалению метод orig() на каждом буфере перекрывать утомительно да и невозможно - он final. А на common и xRecord нельзя свой код писать ) - пока мне кажется что быстро не исправить, придется тупо везде заменять вызовы orig() на свои костыли.
Вложения
Тип файла: xpo SharedProject_GRD_TestOrig_2016_03_22_10_21_NEW_DEV_sapp901_2717.xpo (5.8 Кб, 32 просмотров)

Последний раз редактировалось Logger; 22.03.2016 в 11:12. Причина: Исправил опечатки
За это сообщение автора поблагодарили: gl00mie (2), ex3em (1).