ABAP Object Services – Persistence Service – часть 2

Продолжаем знакомство с ABAP Object Services, в этой части будут рассмотрены темы: менеджеры инстанций и постоянства,  пользовательские проверки при манипуляции с атрибутами хранимых классов, преобразование объектов в структуры и таблицы, загрузка связанных объектов без использования ссылочных атрибутов.

Менеджер инстанций и менеджер постоянства (Persistency Manager)

Как мы уже знаем каждый агент класса, содержит методы для создания, изменения, удаления хранимых объектов, получения хранимых объектов определенного статуса. Данные методы предназначены для хранимых объектов конкретного хранимого класса. Используя менеджер инстанций и менеджер постоянства, мы можем запускать аналогичные методы, не имея ссылки на агент конкретного хранимого класса.

Для доступа к менеджеру инстанции (классу реализующему интерфейс IF_OS_INSTANCE_MANEGER) нужно воспользоваться статическим методом get_instance_manager() класса CL_OS_SYSTEM. Данный класс реализует те же самые методы, что и IF_OS_CA_INSTANCE, за исключением методов для временных хранимых объектов. Кроме того данный класс позволяет получить (изменить SET_STATUS()) статус любого объекта, метод GET_STATUS().

Пример использования менеджера инстанций:

Менеджер постоянства позволяет инициировать объекты с помощью QUERY или таблицы с ключевыми полями, но с обязательным указанием имени класса:

Преобразование объектов в структуры и обратно

Многие сервисы в R/3, как например ALV, не работают напрямую с объектами. Чтобы сформировать ALV, необходимо передать в качестве параметра внутреннюю таблицу. Допустим нам необходимо перенести все хранимые атрибуты объекта в произвольную структуру (имена полей и хранимых атрибутов должны совпадать), для этого напишем следующий код:

methodheader

В коде мы динамически формируем имя метода для получения хранимого атрибута, вызываем его и результат записываем в поле структуры. Получать структуру из объекта мы уже умеем, но для ALV нам нужна таблица, следующий код будет заполнять таблицу относительно таблицы ссылок:

method_objects_to_table

Ну и последний метод – заполнение таблицы относительно объектов класса (статус объекта заполняется опционально):

agent_to_tab

Пример отчета, выводящего данные запроса в ALV:

В некоторых случаях, удобно заполнять объект на основе структуры, реализация аналогична заполнению структуры, только используется вызов метода SET:

str_to_obj

 

Пользовательская проверка при изменении атрибутов

В ходе использования хранимых объектов и их атрибутов перед разработчиком встает задача контроля входных, выходных данных в SET_ GET_ методах. Изменять методы напрямую нельзя, т.к. при повторной генерации хранимого класса они будут перезатерты стандартным кодом.

Выйти из этой ситуации можно несколькими способами:

  • Сделать атрибуты приватными, для доступа к хранимым атрибутам в таком случае придётся писать свои дополнительные методы, например: READ_ATTRNAME, WRITE_ATTRNAME. Из-за объема необходимого к написанию кода данный способ не является оптимальным.
  • Создать дочерний хранимый класс, в котором надо будет переопределить методы доступа к атрибутам и добавить необходимые проверки. Настройки сопоставления наследуются от родительского класса. Нагромождение классов, исходя только из необходимости дополнительных проверок, так же не является самым лучшим решением.
  • В качестве обертки над хранимым классом создать обычный класс с доп. проверками при доступе к хранимым атрибутам. По своей сложности сопоставим с предыдущим.
  • Ну и наконец, самым лучшим с точки зрения оптимальности, является способ использования Enhancement Framework. Дополнительная проверка в таком случае вставляется через расширение метода перед началом выполнения основного кода (неявная точка расширения), при повторной генерации класса, затирается только сгенерированная часть, проверки в расширении остаются не тронутыми.

 

Загрузка вложенных объектов без хранимых атрибутов

Рассмотренные ранее ссылочные атрибуты, когда один объект, через свой атрибут, ссылается на другой и система его автоматически подгружает, не могут быть использованы для связи один ко многим.  Реализовать подобную схему можно следующим образом:

  • Внутри класса создать временный атрибут содержащий таблицу ссылок на вложенные объекты и флаг, указывающий на то, что они были загружены. В качестве примера возьмем хранимый класс «факультет» включающий в себя внутреннюю таблицу со ссылками на объекты хранимого класса «студент» — gt_students (TYPE STANDART TABLE OF REF TO zcl_student). Флаг загруженности – students_loaded.
  • Создать метод для получения внутренней таблицы со ссылками на студентов – get_students, метод должен содержать примерно следующий код (обработка исключений опущена):

    По аналогии можно написать метод для получения ссылки на конкретного студента из внутренней таблицы, относительно его идентификатора. Метод должен быть вызван на этапе инициализации объекта «Факультет».
  • Так как объект «факультет» может быть удален из памяти PS (через метод RELEASE), надо позаботиться о том, чтобы инициализировать временные атрибуты — таблицу со ссылками на студентов и флаг. Делается это через определение метода INVALIDATE:

В следующей части будут рассмотрены вопросы интеграции с системой блокировок SAP и переопределение методов доступа к данным.

  • Андрей

    Отличный цикл статей про abap-object-services-persistence, спасибо.
    Когда ожидается след.часть про интеграцию с системой блокировок и переопределение методов?

    • Astrafox

      Спасибо за комментарий, на следующей неделе точно ожидается.