No todos los datos empresariales caben perfectamente en tablas planas. Los catálogos de productos, los organigramas y las estructuras de cuentas a menudo se basan en relaciones entre padres e hijos que los modelos de datos estándar no pueden representar bien.
Por ejemplo, en un escenario de venta minorista de comestibles, es posible que sea necesario agrupar los productos en varios niveles, como departamento, categoría, subcategoría y artículo, para que los usuarios comerciales puedan mantener estructuras de productos de manera consistente en una aplicación.
Esta es una buena opción para el Modelo de programación de aplicaciones ABAP RESTful (RAP), porque RAP proporciona una forma estructurada de modelar objetos comerciales transaccionales, definir composiciones padre-hijo, permitir el manejo de borradores, exponer servicios OData V4 y generar un SAP Fiori Experiencia de usuario basada en elementos con menos código personalizado.
Considere un artículo comestible común como «Gala Apple 1kg». El siguiente ejemplo muestra cómo se puede modelar y gestionar su jerarquía en el sistema.
|
Este tipo |
Este valor |
Padre |
Ruta de jerarquía calculada |
|
DEPARTAMENTO |
Alimento |
— |
Alimento |
|
GATO |
Productos frescos |
Alimento |
Alimentos → Productos frescos |
|
SUBCATE |
frutas |
Productos frescos |
Alimentos → Productos frescos → Frutas |
|
ARTÍCULO |
manzanas |
frutas |
Alimentos → Productos frescos → Frutas → Manzanas |
Debido a que cada nodo de jerarquía puede ser hijo de un nodo de nivel superior y padre de nodos de nivel inferior, el modelo es recursivo. Un modelo de datos planos estándar no puede representar esta estructura de forma eficaz. La solución requiere una tabla de autorreferencia y un marco que pueda gestionar de forma segura la complejidad transaccional de la edición de datos jerárquicos.
Esta publicación explicará cómo se puede aplicar RAP a este caso de uso de jerarquía de productos de una tienda de comestibles: un escenario práctico y con el que se puede identificar que demuestra los conceptos clave sin agregar complejidad innecesaria al dominio.
La aplicación que usaremos sigue la arquitectura estándar en capas RAP. Cada capa tiene una responsabilidad clara, lo que hace que la solución sea más fácil de mantener, probar y ampliar, al mismo tiempo que se alinea con los principios básicos limpios de SAP para el desarrollo personalizado.
|
Capa |
Artefacto |
Objetivo |
|
Persistencia |
ZPRODUCT_HDR ZPRODUCT_HIER |
Almacenamiento de bases de datos para productos y nodos de jerarquía. |
|
CDS básicos |
ZI_Product_B ZI_ProductHierarchy_B |
Alias de campos semánticos + cálculo de ruta de jerarquía |
|
Interfaz CDS |
ZI_Product_I ZI_ProductHierarchy_I |
Entidad raíz RAP + composición + asociaciones |
|
CDS de consumo |
ZC_Product ZC_ProductHierarchy |
Proyección preparada para SAP Fiori + redirecciones de asociación |
|
Definición de comportamiento. |
BDEF en ZI_Product_I |
CRUD, ciclo de vida del borrador, numeración gestionada |
|
Capa de servicio |
ZUI_PRODUCT_O4 (Def. + Encuadernación) |
Exposición de OData V4 para elementos de SAP Fiori |
|
Anotaciones de la interfaz de usuario |
MDE en ZC_Product MDE en ZC_ProductHierarchy |
Metadatos de diseño de elementos de SAP Fiori |
En RAP, las vistas CDS de la interfaz definen el límite del objeto comercial. Las vistas de CDS de consumo dan forma a los datos para la interfaz de usuario. La definición de comportamiento controla qué operaciones están permitidas y cómo se conservan los datos. Estas tres preocupaciones siempre se mantienen en artefactos separados.
La solución se basa en dos tablas de bases de datos. La tabla de encabezado de producto almacena el registro maestro del producto, mientras que la tabla de jerarquía almacena nodos de jerarquía con una clave externa autorreferenciada que establece la relación padre-hijo entre nodos.
Tenga en cuenta que los borradores de tablas (sufijo _D) para ambas tablas son generados automáticamente por el ABAP sistema cuando se activa la definición de comportamiento. No es necesario crearlos manualmente.
Las vistas CDS desempeñan un papel central en la definición de la estructura jerárquica. El siguiente ejemplo ilustra cómo se pueden modelar y gestionar eficazmente las jerarquías de productos.
Las vistas de interfaz definen la estructura del objeto comercial RAP. La entidad raíz declara la composición a la entidad secundaria, mientras que la entidad secundaria declara asociaciones inversas y autoasociaciones para la navegación principal e secundaria.
define root view entity ZI_Product_I
as select from ZI_Product_B
composition [0..*] of ZI_ProductHierarchy_I as _Hierarchy
association [0..*] to ZI_Product_B as _ProductType
on $projection.ProductType = _ProductType.ProductType
{
key ProductID,
ProductName,
@ObjectModel.foreignKey.association: '_ProductType'
ProductType,
ProductImageUrl,
LastChangedAt,
LocalLastChangedAt,
_Hierarchy,
_ProductType
}
la composicion [0..*] La declaración convierte a ZI_ProductHierarchy_I en una entidad secundaria de esta raíz. Todos los nodos de jerarquía de un producto se gestionan como parte del mismo objeto comercial transaccional y comparten el mismo bloqueo.
La vista secundaria expone los datos del nodo de la jerarquía y declara tres asociaciones: una asociación principal con el producto raíz y dos autoasociaciones para la navegación hacia arriba (_Parent) y hacia abajo (_Children) dentro de la jerarquía.
define view entity ZI_ProductHierarchy_I
as select from ZI_ProductHierarchy_B
association to parent ZI_Product_I as _Product
on $projection.ProductID = _Product.ProductID
association [0..1] to ZI_ProductHierarchy_I as _Parent
on $projection.ParentHierID = _Parent.HierID
and $projection.ProductID = _Parent.ProductID
association [0..*] to ZI_ProductHierarchy_I as _Children
on $projection.HierID = _Children.ParentHierID
and $projection.ProductID = _Children.ProductID
{
key HierID,
ProductID,
ParentHierID,
HierType,
HierValue,
HierarchyPath,
LastChangedAt,
LocalLastChangedAt,
_Product,
_Parent,
_Children
}
Las vistas de consumo se proyectan desde vistas de interfaz y redirigen asociaciones a sus contrapartes de consumo. Esto completa la cadena de composición de RAP y prepara las entidades para SAP Fiori.
@Metadata.allowExtensions: true
@UI.headerInfo: {
typeName: 'Product',
typeNamePlural: 'Products',
title: { value: 'ProductName' },
description: { value: 'ProductType' },
imageUrl: 'ProductImageUrl'
}
define root view entity ZC_Product
provider contract transactional_query
as projection on ZI_Product_I
{
key ProductID,
ProductName,
ProductType,
@Semantics.imageUrl: true
ProductImageUrl,
_Hierarchy : redirected to composition child ZC_ProductHierarchy
}
@Metadata.allowExtensions: true
define view entity ZC_ProductHierarchy
as projection on ZI_ProductHierarchy_I
{
@ObjectModel.text.element: [ 'HierValue' ]
key HierID,
ProductID,
@ObjectModel.text.element: [ 'ParentHierValue' ]
ParentHierID,
_Parent.HierValue as ParentHierValue,
HierType,
HierValue,
HierarchyPath,
_Product : redirected to parent ZC_Product,
_Parent : redirected to ZC_ProductHierarchy,
_Children : redirected to ZC_ProductHierarchy
}
La definición de comportamiento especifica las capacidades transaccionales del objeto comercial RAP. Esta solución utiliza una implementación administrada con soporte para borradores. Las dos entidades (Producto como raíz y Nodo de jerarquía como hijo) desempeñan funciones diferentes y, por lo tanto, requieren diferentes configuraciones de comportamiento.
|
Aspecto |
Entidad de producto |
Entidad de jerarquía |
|
Entidad |
ZI_Producto_I (Producto) |
ZI_ProductHierarchy_I (nodo de jerarquía) |
|
Role |
Lock master: posee el borrador del ciclo de vida |
Dependiente del bloqueo: hereda el bloqueo del Producto |
|
Tabla persistente |
ZPRODUCT_HDR |
ZPRODUCT_HIER |
|
Borrador de tabla |
ZPRODUCT_HDR_D (generado automáticamente) |
ZPRODUCT_HIER_D (generado automáticamente) |
|
Operaciones |
crear, actualizar, eliminar |
actualizar, eliminar (crear mediante composición) |
|
Proyectos de acciones |
Editar, Reanudar, Preparar, Activar optimizado, Descartar |
Heredado de raíz; con borrador en _Producto |
|
Numeración de claves |
product_id — proporcionado por el usuario |
hier_id — administrado (UUID generado automáticamente por RAP) |
|
Asociación |
_Jerarquía { crear; con borrador; } |
_Producto, _Padres, _Niños |
|
Estrategia de bloqueo |
etiqueta total en LastChangedAt |
etiqueta maestra en LocalLastChangedAt |
Las decisiones de diseño más importantes en la definición de comportamiento son:
Las extensiones de definición de servicio y anotación de metadatos completan la pila de aplicaciones. La definición de servicio especifica qué entidades se exponen a través de OData V4, mientras que las extensiones de anotación definen cómo los elementos de SAP Fiori representan esas entidades en el informe de lista y la página de objetos.
A continuación se muestra un ejemplo de una página de lista:

Y aquí hay un ejemplo de una página de objeto:

La definición del servicio expone cuatro entidades. Dos son transaccionales y dos sirven únicamente para fines de ayuda económica:
|
Entidad |
Role |
Objetivo |
|
ZC_Producto |
Transaccional (raíz) |
Principal punto de entrada para la aplicación SAP Fiori. Expone el informe de lista de productos y la página de objetos. |
|
ZC_ProductHierarchy |
Transaccional (niño) |
Expone nodos de jerarquía dentro de la página del objeto del producto a través de la asociación de composición. |
|
ZI_Producto_B |
Ayuda de valor |
Proporciona la ayuda de valor ProductType en los formularios de creación y edición de productos. |
|
ZI_ParentHierVH |
Ayuda de valor |
Proporciona la selección del nodo de la jerarquía principal, cuyo ámbito es ProductID para evitar asignaciones entre productos. |
Una práctica recomendada es exponer solo las entidades que la interfaz de usuario realmente necesita. La exposición innecesaria de entidades aumenta la superficie de ataque del servicio y puede degradar el rendimiento de los metadatos de OData en entornos grandes.
Los archivos de extensión de metadatos aplican anotaciones de UI a las vistas de consumo sin modificar las vistas CDS mismas. La siguiente tabla muestra algunos ejemplos de anotaciones utilizadas en la aplicación.
|
Anotación |
Aplicado a |
Valor/Configuración |
Efecto en SAP Fiori Elements |
| @UI.faceta | Ambas vistas |
#IDENTIFICACIÓN_REFERENCIA #LINEITEM_REFERENCE |
Agrupa campos en secciones de página de objetos. |
| @UI.lineItem | Ambas vistas | posición: 10, 20, 30 | Controla qué campos aparecen como columnas en la tabla del informe de lista y en la tabla integrada de elementos de jerarquía. |
| @UI.selectionField | Ambas vistas | posición: 10, 20, 30 | Agrega campos a la barra de filtro encima del informe de lista. |
| @identificación UI | Ambas vistas | posición: 10, 20, 30 | Coloca campos en la sección Información general en la página del objeto. |
| @UI.textArrangement |
Tipo de producto ParentHierID |
#TEXT_ONLY | Oculta el valor de la clave sin formato y muestra solo el texto descriptivo en el campo de la interfaz de usuario. |
| @Consumo.valorAyudaDefinición |
Tipo de producto ParentHierID |
ZI_Producto_B ZI_ParentHierVH |
Muestra un cuadro de diálogo de ayuda para entradas del campo. La ayuda de la jerarquía principal utiliza enlaces adicionales para alcanzar el alcance por ID de producto. |
| @UI.oculta | PadreHierValue | verdadero | Mantiene el campo de texto derivado invisible en la interfaz de usuario mientras aún está disponible para la resolución de texto a través de @ObjectModel.text.element. |
| @Semántica.imageUrl | URL de imagen del producto | Indica a los elementos de SAP Fiori que representen el valor del campo como una URL de imagen y muestren la miniatura de la imagen en la lista. |
Los siguientes puntos resaltan los aspectos más importantes de esta solución.
Esta publicación se publicó originalmente el 7/2026.
Calle Eloy Gonzalo, 27
Madrid, Madrid.
Código Postal 28010
Paseo de la Reforma 26
Colonia Juárez, Cuauhtémoc
Ciudad de México 06600
Real Cariari
Autopista General Cañas,
San José, SJ 40104
Av. Jorge Basadre 349
San Isidro
Lima, LIM 15073
