Verificación de la clave semántica

En el modelo de programación de aplicaciones ABAP RESTful, la clave de una tabla de base de datos a menudo se compone del campo de cliente y un campo UUID, cuyo valor se asigna automáticamente por el tiempo de ejecución cuando crea una nueva instancia del business object. Esta combinación de campos es suficiente para garantizar que el sistema pueda identificar cada registro en la tabla de forma unívoca. Sin embargo, además de esta clave técnica, nuestro objeto también tiene una clave semántica, en este caso la combinación de compañía aérea y número de vuelo, que también debe ser unívoca según la lógica empresarial. Para garantizar la univocidad de esta combinación de campos, debe implementar su propia verificación en forma de validación.
Las validaciones se declaran en la definición de comportamiento de la entidad de vista CDS y se implementan en la clase de implementación de comportamiento.
Verificaciones de entrada en la aplicación
Además de verificar la clave semántica, hay otras verificaciones que debe realizar. Por ejemplo, aunque la aplicación generada le permite crear, leer, actualizar y borrar datos, aún no contiene verificaciones de consistencia. En consecuencia, puede crear conexiones de vuelos para compañías aéreas que no existen o en las que los aeropuertos de salida y de destino son los mismos.

Para evitar que esto ocurra, defina otras validaciones en la definición de comportamiento e impleméntelas en la clase de implementación de comportamiento.
Creación de textos de mensaje
Antes de crear la validación, debe crear los textos que desea visualizar. Esto se realiza mediante una clase de mensaje. Una clase de mensaje es una colección de hasta 1000 mensajes que pertenecen a un área de aplicación determinada. Como se muestra en la figura, cada texto tiene un número que identifica el mensaje de forma unívoca dentro de la clase de mensaje.

Para crear una nueva clase de mensaje, proceda de la siguiente manera:
Seleccione Fichero→Nuevo→Otro… y escriba mensaje en el campo de filtro.
Haga doble clic en la entrada Clase de mensaje en la lista de aciertos y, a continuación, introduzca un paquete, un nombre y una descripción para la nueva clase de mensaje. Seleccione Siguiente.
Asigne la clase de mensaje a una orden de transporte y seleccione Finalizar.
Los mensajes también pueden contener reserva-espacios, que se sustituyen por valores concretos cuando se visualiza el mensaje. Los marcadores de posición se indican con el signo & seguido de un número. Puede utilizar hasta cuatro marcadores de posición en cada mensaje.
Definición de la validación
Para definir una validación, añada una declaración de validación a la definición de comportamiento de su business object. En este ejemplo, la validación debe realizarse cada vez que el usuario guarda un registro de datos, y podría ser cuando crea el registro o si lo modifica posteriormente.

Cuando define la validación en la definición de comportamiento, un mensaje de advertencia le indica que el método correspondiente no existe. Utilice una corrección rápida (combinación de teclas CTRL + 1) para añadir el método a la implementación de comportamiento. La implementación de comportamiento es una clase local dentro de su pool de comportamientos. La definición del método contiene el suplemento FOR VALIDATE ON SAVE, que lo identifica como la implementación de la validación. Tiene un parámetro de importación KEYS. Se trata de una tabla interna que contiene las claves de los objetos creados o modificados. Se utilizan para leer los datos reales que el usuario ha introducido.
El suplemento FOR Connection~CheckSemanticKey enlaza el método con la validación CheckSemanticKey de la definición de comportamiento. Aquí, Conexión es el nombre alias de la entidad de vista Z_R_CONNECTION.

Al definir una validación, también debe crear su implementación. Este es un método en el pool de comportamiento. La forma más fácil de hacerlo es utilizar una solución rápida. Sitúe el cursor en el nombre de la validación y pulse CTRL + 1. ADT propone crear el método. Haga doble clic en la propuesta para crear el método.
El proceso de validación
Nota

Cuando el sistema desencadena una validación, llama la implementación correspondiente. El parámetro de importación KEYS contiene las claves de los registros de datos modificados. Utilice las claves para leer los campos de los registros que necesita mediante Entity Manipulation Language (EML). EML es un conjunto especial de sentencias en ABAP que le permite abordar business objects.
Una vez leídos los datos, puede realizar las verificaciones que necesite. Si la verificación falla, deberá emitir un mensaje de error adecuado y, lo que es más importante, decirle al framework que no escriba las modificaciones en la base de datos.

La primera tarea en una validación es leer la entrada de usuario. Para ello, utilice la sentencia Entity Manipulation Language (EML) READ ENTITIES. Las claves de los registros de datos correspondientes se transfieren a la validación mediante las claves de parámetro de importación.
Los campos que necesita para validar la clave semántica son CarrierID para la compañía aérea y ConnectionID para el número de vuelo.
El fragmento de código utiliza la palabra clave CORRESPONDING y una declaración en línea para el conjunto de resultados. A continuación, puede ver el código equivalente utilizando variables definidas explícitamente, lo que facilita la comprensión de los tipos que se utilizan.
12345678910111213
DATA read_keys TYPE TABLE FOR READ IMPORT zs4d400_r_connection.
DATA connections TYPE TABLE FOR READ RESULT zs4d400_r_connection.
read_keys = CORRESPONDING #( keys ).
READ ENTITIES OF zs4d400_r_connection IN LOCAL MODE
ENTITY Connection
FIELDS ( CarrierID ConnectionID )
WITH read_keys
RESULT connections.
Una vez leída la entrada de usuario, puede utilizar los valores de CarrierID y ConnectionID para ver si esta clave semántica ya se ha utilizado en otro conjunto de datos distinto al que está procesando. Dado que la combinación de claves podría estar en la tabla activa o en la tabla borrador, debe buscar en ambas y la forma más eficiente de hacerlo es con una unión.

El conjunto de resultados de esta consulta siempre debe estar vacío. De lo contrario, hay más registros con la misma combinación de CarrierID y ConnectionID, lo que significa que el registro que el usuario está intentando crear actualmente es un duplicado y debe rechazarse.

Si la combinación de ID de transportista e ID de conexión ya existe, habrá una entrada en la tabla check_result. En este caso, debe emitir un mensaje.
El primer paso es crear un objeto de mensaje. Para ello, utilice la autoreferencia y llame al método new_message( ). El ID, el número y la gravedad de los parámetros son obligatorios. ID es el nombre de la clase de mensaje que contiene el mensaje; el número es el número de mensaje. La gravedad clasifica el mensaje como mensaje de éxito, información, advertencia o error. La clase de implementación de comportamiento contiene una constante estructurada ms cuyos componentes representan los diferentes niveles de gravedad. En este caso, necesita el nivel de gravedad ms-error.
El método también tiene parámetros de importación opcionales v1, v2, v3 y v4. Se utilizan para sustituir marcadores de posición por valores concretos. En este ejemplo, el marcador de posición &1 se sustituye por el código de aerolínea, el marcador de posición &2 se sustituye por el número de vuelo.
El resultado de la llamada de método es una referencia de objeto. En el siguiente paso, pasará el objeto al tiempo de ejecución para que el mensaje de error se devuelva al servicio OData y se visualice en la vista previa de la aplicación.

Para que el tiempo de ejecución muestre un mensaje, debe notificarlo mediante la estructura notificada. Este es un parámetro changing implícito de todos los métodos de validación y es una estructura profunda. Contiene un componente con el nombre alias de la entidad. Este componente es una tabla interna.
Para notificar el mensaje, debe hacer tres cosas:
- Añada la clave del registro afectado a la tabla interna. Puede hacerlo utilizando el grupo de campos %tky. Cuando agrupa campos como este, puede direccionar el nombre del grupo en lugar de tener que dirigirse a cada campo individualmente.
- Adjunte el objeto de mensaje a la tabla. Para ello, asigne la referencia de objeto del objeto de mensaje al componente %msg de la tabla interna.
- Vincule el mensaje al campo afectado. Esto garantiza que el campo se resalte en la aplicación. Esto, a su vez, ayuda al usuario a navegar mejor por la aplicación. Para ello, utilice el componente %element de la tabla interna.

En este ejemplo, reported_record es una estructura con el tipo de línea de la tabla interna reported-connection. Rellene el componente %tky con el contenido del grupo de campos %tky en la conexión de estructura. Esta estructura de conexión se utiliza como área de trabajo para la tabla interna que contiene los datos introducidos por el usuario. A continuación, asigne el objeto de mensaje que ha creado utilizando el método new_message( ) al componente %msg. Finalmente, para vincular el mensaje a los campos CarrierID y ConnectionID, utilice la estructura %element. %element contiene un componente para cada campo de la entidad. Si fija un componente en verdadero, el campo de entrada correspondiente se resaltará en la aplicación. Para ello, utilice la constante estructurada if_abap_behv=>mk. Este tiene el componente activado para marcado/verdadero y desactivado para no marcado/falso.
No puede utilizar las constantes globales abap_true y abap_false en este punto, ya que sus tipos de datos no son compatibles.

Además de emitir el mensaje, también debe indicar al tiempo de ejecución que no guarde los datos incorrectos. Para ello, utilice la estructura fallida del método de validación. Fallido es un parámetro changing implícito que está presente en todos los métodos de validación.
Para notificar un registro como fallido, agregue su grupo de campos %tky al grupo de campos %tky de la tabla interna. Fallo de conexión.

La siguiente validación verifica que la compañía aérea que ha introducido el usuario exista realmente. El primer paso es leer la entrada de usuario utilizando la sentencia EML READ ENTITIES. Esta vez, solo necesita leer el campo CarrierID.

La sentencia SELECT SINGLE lee los datos mediante la entidad de vista CDS /dmo/i_carrier y verifica si existe la compañía aérea indicada. Si es así, el valor de la constante global abap_true ("X") se coloca en el campo. Si existe es inicial siguiendo la sentencia SELECT, debe emitir un mensaje, notificarlo y añadir el registro a la estructura fallida como lo hizo en el ejemplo anterior.
La validación final comprueba que los aeropuertos de origen y destino son diferentes. El primer paso es leer la entrada de usuario mediante una sentencia READ ENTITIES. Esta vez, los campos AirportFromID y AirportToID son relevantes.


Si los aeropuertos de salida y llegada son los mismos, debe emitir el mensaje correspondiente y rellenar las estructuras notificadas y fallidas. El extracto de código muestra la codificación relevante para crear el mensaje. La codificación para rellenar las estructuras notificadas y fallidas es la misma que en los ejemplos anteriores.






