Le Numbering dans RAP définit quand et comment les clés primaires sont attribuées pour les nouvelles instances de Business Object. Le choix entre Early et Late Numbering a un impact direct sur l’architecture de votre application.
Concept de base
| Stratégie | Moment | Clé disponible | Cas d’usage |
|---|---|---|---|
| Early Numbering | À CREATE | Immédiatement après création | Standard pour la plupart des scénarios |
| Late Numbering | À SAVE | Seulement après sauvegarde | Number Ranges externes, systèmes legacy |
Quelle stratégie choisir ?
Choisir Early Numbering si :
- La clé est nécessaire immédiatement après la création
- Les Child-Entities doivent être référencées directement
- Le numéro provient d’un Number Range interne
- Vous avez un scénario Managed sans dépendances legacy
Choisir Late Numbering si :
- Le numéro est attribué par un système externe
- Un Number Range externe est utilisé (ex. numéros de documents)
- L’attribution de numéro ne doit avoir lieu qu’à la sauvegarde
- Des scénarios Draft avec attribution ultérieure de numéros sont nécessaires
Early Numbering
Avec Early Numbering, la clé est attribuée directement lors du CREATE. Le framework prend en charge l’attribution de numéro automatiquement ou vous l’implémentez vous-même.
Managed Early Numbering
Le scénario le plus simple : Le framework attribue automatiquement des UUID ou vous utilisez des Number Ranges.
managed implementation in class zbp_i_travel unique;strict ( 2 );
define behavior for ZI_Travel alias Travelpersistent table ztravellock masterauthorization master ( instance )etag master LastChangedAt{ create; update; delete;
// Automatische Nummernvergabe durch das Framework (UUID) field ( numbering : managed ) TravelUUID;
// Alternative: Schlüssel ist readonly, wird in Determination gesetzt field ( readonly ) TravelId;}Early Numbering avec Number Range
Pour des numéros séquentiels provenant d’un Number Range :
managed implementation in class zbp_i_travel unique;strict ( 2 );
define behavior for ZI_Travel alias Travelpersistent table ztravellock masterauthorization master ( instance )etag master LastChangedAtearly numbering{ create; update; delete;
// Readonly, da früh vergeben field ( readonly ) TravelId;}Implémentation de Early Numbering
CLASS lhc_travel DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS earlynumbering_create FOR NUMBERING IMPORTING entities FOR CREATE Travel.ENDCLASS.
CLASS lhc_travel IMPLEMENTATION.
METHOD earlynumbering_create. DATA: lv_travel_id TYPE /dmo/travel_id.
" Number Range Object und Intervall DATA(lv_nr_object) = 'ZTRAVEL'. DATA(lv_nr_interval) = '01'.
LOOP AT entities INTO DATA(ls_entity) WHERE TravelId IS INITIAL. TRY. " Nummer aus Number Range holen cl_numberrange_runtime=>number_get( EXPORTING nr_range_nr = lv_nr_interval object = lv_nr_object IMPORTING number = DATA(lv_number) ).
lv_travel_id = lv_number.
" Mapping: %cid -> generierter Schlüssel APPEND VALUE #( %cid = ls_entity-%cid %key = ls_entity-%key %is_draft = ls_entity-%is_draft TravelId = lv_travel_id ) TO mapped-travel.
CATCH cx_number_ranges INTO DATA(lx_nr). " Fehler bei Nummernvergabe APPEND VALUE #( %cid = ls_entity-%cid %key = ls_entity-%key %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = lx_nr->get_text( ) ) ) TO reported-travel.
APPEND VALUE #( %cid = ls_entity-%cid %key = ls_entity-%key ) TO failed-travel. ENDTRY. ENDLOOP. ENDMETHOD.
ENDCLASS.Late Numbering
Avec Late Numbering, la clé est attribuée seulement lors de la sauvegarde. Jusqu’alors, le système travaille avec des ID temporaires (%pid - preliminary ID).
Cas d’usage pour Late Numbering
- Number Ranges externes qui ne sont disponibles qu’au commit
- Systèmes legacy qui attribuent les numéros lors de la sauvegarde
- Numéros de documents qui ne sont créés qu’à la comptabilisation finale
- Scénarios Draft où le numéro final n’est attribué qu’à l’activation
Behavior Definition Late Numbering
managed implementation in class zbp_i_travel unique;strict ( 2 );
define behavior for ZI_Travel alias Travelpersistent table ztravellock masterauthorization master ( instance )etag master LastChangedAtlate numbering{ create; update; delete;
// Schlüssel wird erst bei SAVE vergeben field ( readonly ) TravelId;}Implémentation de Late Numbering
CLASS lsc_travel DEFINITION INHERITING FROM cl_abap_behavior_saver. PROTECTED SECTION. METHODS adjust_numbers REDEFINITION.ENDCLASS.
CLASS lsc_travel IMPLEMENTATION.
METHOD adjust_numbers. DATA: lv_travel_id TYPE /dmo/travel_id.
" Number Range Object und Intervall DATA(lv_nr_object) = 'ZTRAVEL'. DATA(lv_nr_interval) = '01'.
" Alle neuen Einträge ohne finale Nummer LOOP AT mapped-travel ASSIGNING FIELD-SYMBOL(<ls_travel>) WHERE %is_draft = if_abap_behv=>mk-off.
IF <ls_travel>-TravelId IS INITIAL. TRY. " Nummer aus Number Range holen cl_numberrange_runtime=>number_get( EXPORTING nr_range_nr = lv_nr_interval object = lv_nr_object IMPORTING number = DATA(lv_number) ).
" Finale Nummer zuweisen <ls_travel>-TravelId = lv_number.
CATCH cx_number_ranges INTO DATA(lx_nr). " Fehlerbehandlung RAISE SHORTDUMP lx_nr. ENDTRY. ENDIF. ENDLOOP. ENDMETHOD.
ENDCLASS.Late Numbering avec Draft
Dans les scénarios Draft avec Late Numbering, le draft travaille avec un ID préliminaire. Le numéro final n’est attribué qu’à l’activation :
managed implementation in class zbp_i_travel unique;strict ( 2 );with draft;
define behavior for ZI_Travel alias Travelpersistent table ztraveldraft table zdraft_travellock master total etag LastChangedAtauthorization master ( instance )etag master LastChangedAtlate numbering{ create; update; delete;
field ( readonly ) TravelId;
draft action Edit; draft action Activate optimized; draft action Discard; draft action Resume; draft determine action Prepare;}Managed vs Unmanaged Numbering
Managed Numbering
Le framework prend en charge l’attribution complète des numéros :
define behavior for ZI_Travel alias Travel{ // UUID wird automatisch generiert field ( numbering : managed ) TravelUUID;}Avantages :
- Aucun code requis
- UUID garantis uniques
- Disponible immédiatement (Early)
Inconvénients :
- Uniquement des UUID possibles
- Pas de numéros parlants
Unmanaged Numbering (Early)
Vous implémentez l’attribution de numéro vous-même à CREATE :
define behavior for ZI_Travel alias Travelearly numbering{ field ( readonly ) TravelId;}Avantages :
- Contrôle total sur le format de numéro
- Number Ranges possibles
- Clé disponible immédiatement
Inconvénients :
- Plus d’effort d’implémentation
- Vous devez assurer l’unicité
Unmanaged Numbering (Late)
Vous implémentez l’attribution de numéro à SAVE :
define behavior for ZI_Travel alias Travellate numbering{ field ( readonly ) TravelId;}Avantages :
- Number Ranges externes possibles
- Numéros seulement au commit
- Séquence de numéros sans lacune possible
Inconvénients :
- Clé inconnue pendant la transaction
- Référencement de Child-Entities plus complexe
- Gestion de %pid requise
Gestion de %pid (Preliminary ID)
Avec Late Numbering, le framework utilise un ID préliminaire (%pid) jusqu’à ce que le numéro final soit attribué :
" CREATE mit Late NumberingMODIFY ENTITIES OF zi_travel ENTITY Travel CREATE FIELDS ( AgencyId CustomerId ) WITH VALUE #( ( %cid = 'CID_1" " TravelId ist noch nicht bekannt! AgencyId = '000001" CustomerId = '000010" ) ) MAPPED DATA(mapped) FAILED DATA(failed) REPORTED DATA(reported).
" Mapped enthält %pid statt finalem Schlüssel" mapped-travel[ 1 ]-%pid ist gesetzt" mapped-travel[ 1 ]-TravelId ist initial
" Erst nach COMMIT ENTITIES ist TravelId gesetztCOMMIT ENTITIES.Child-Entities avec Late Numbering
Pour les relations Parent-Child avec Late Numbering :
" Behavior Definitiondefine behavior for ZI_Travel alias Travellate numbering{ association _Booking { create; }}
define behavior for ZI_Booking alias Booking{ // Booking referenziert Travel über %pid}" EML: Create Parent und Child gleichzeitigMODIFY ENTITIES OF zi_travel ENTITY Travel CREATE FIELDS ( AgencyId CustomerId ) WITH VALUE #( ( %cid = 'TRAVEL_1' AgencyId = '000001' CustomerId = '000010' ) )
CREATE BY \_Booking FIELDS ( BookingId FlightDate ) WITH VALUE #( ( %cid_ref = 'TRAVEL_1' " Referenz auf Parent via %cid %target = VALUE #( ( %cid = 'BOOKING_1" BookingId = '0001" FlightDate = sy-datum ) ) ) ) MAPPED mapped FAILED failed REPORTED reported.Matrice de décision
| Critère | Early + Managed | Early + Unmanaged | Late |
|---|---|---|---|
| UUID comme clé | ✅ Idéal | ❌ | ❌ |
| Number Range (interne) | ❌ | ✅ Idéal | ⚠️ Possible |
| Number Range (externe) | ❌ | ❌ | ✅ Idéal |
| Clé disponible immédiatement | ✅ | ✅ | ❌ |
| Référencement Child | Simple | Simple | Via %pid |
| Effort d’implémentation | Minimal | Moyen | Plus élevé |
| Intégration legacy | ❌ | ⚠️ | ✅ Idéal |
Bonnes pratiques
- Managed Numbering par défaut - Utilisez UUID et
numbering : managedsi possible - Early Numbering pour Number Ranges - Si vous avez besoin de numéros parlants, mais que le numéro doit être disponible immédiatement
- Late Numbering uniquement si nécessaire - Seulement pour les systèmes externes ou besoins spéciaux
- Utiliser %cid de manière cohérente - Particulièrement important avec Late Numbering pour les références Parent-Child
- Gestion des erreurs - Les Number Ranges peuvent générer des erreurs (Overflow, Lock)
- Testabilité - Late Numbering complique les tests unitaires, car les clés ne sont connues que tardivement
Sujets avancés
- RAP Grundlagen - Introduction au RESTful ABAP Programming Model
- Draft Handling in RAP - Sauvegarde temporaire pour workflows complexes
- RAP Actions et Functions - Implémenter la logique métier