Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Deleting a permanent object from the table messes up the loop flow

ceieneka
Explorer
425

Hi,

I'm starting to play with abap and I have this problem. I get objects of persistent class into table and than iterate through it in a loop and call method which check some condition, if the condition is met I delete such object, Unfortunately this deleting breaks the loop. Here is simplify code:

...
lt_msgs = lo_agent->get_persistent_by_query( i_query = lo_query ).
LOOP AT lt_msgs INTO lo_record.
  lo_msg ?= lo_record.
  lo_msg->process( ).
ENDLOOP.

And here is the process() method:

...
  IF me->get_is_active( ) = 0.
    zca_sd_pz_msg=>agent->if_os_factory~delete_persistent( me ).
    COMMIT WORK.
  ENDIF.
endmethod.

After the first deletion in the process() method, the next objects passed through the outer loop appear to be empty - logic of process method works fine until first delete.

What I missed?

4 REPLIES 4

horst_keller
Product and Topic Expert
Product and Topic Expert
267

Hi,

Starting "playing with ABAP" and using persistent objects from the beginning?

Hmm, quite a task.

In fact "Object Services" are a non-trivial framework and no longer recommended anyhow (since we have RAP now).

Therefore, better start.with something more basic or, well, delve deeper:

Object Services (OS)

ceieneka
Explorer
267

It took me a while to find a solution, the problem was in the way the commits were made.
Whenever a commit occurred in the process() method, it "cleared" other lt_msgs array records. Commit from the process method should be called once, after processing all objects from the loop. It should be done like this (at least it works):

...
lt_msgs = lo_agent->get_persistent_by_query( i_query = lo_query ).
LOOP AT lt_msgs INTO lo_record.
lo_msg ?= lo_record.
lo_msg->process( ).
ENDLOOP.
COMMIT WORK.
...
IF me->get_is_active( ) = 0.
zca_sd_pz_msg=>agent->if_os_factory~delete_persistent( me ).
ENDIF.
endmethod.

horst.keller : this is deep water trial 🙂

Thanks.

harishankar714
Participant
267

It seems that the issue is with the way the loop is being processed after an object is deleted. When you delete an object in the loop, the size of the table that holds the objects is reduced and this causes the loop to terminate prematurely.

To resolve this issue, you could use a different approach to iterate through the objects. One possible solution is to use a backward loop and delete the objects from the end of the table. This way, even if an object is deleted, the loop will continue to run until all the objects are processed.

0 Kudos
267

I thought about it, but the debugger was showing the same number of objects in the array with each iteration except that each object had empty fields. I'll give it a shot for training purposes when I have a moment.