Application Development and Automation 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: 
Read only

ReKeyed Copy of a Persistent Object

mike_mcinerney
Participant
0 Kudos
558

I have a persistent object that has the attributes:

Key1

Key2

Key_EffectiveDate

NonKey1

NonKey2

NonKey3

...

NonKeyn

I'd like to make a persistent copy of an object of this class, changing only the (key) effective date,

and retaining all the non key values.

Is there an easy way to do this?

I do not want to run a method that needs to have all the non-key attributes passed to it.

Rather, I want to run something that looks like


  =>createPersistentCopy(  OldKey = ... .. .
                           NewKey = ... .. .
                           returning newObjectRef ) 

( This is for an app we are creating that uses date delimited objects)

Thanks...

...Mike

1 ACCEPTED SOLUTION
Read only

Former Member
0 Kudos
442

just in case, if you do not want to work with the structure name as in the above example, you can also use the class CL_ABAP_OBJECTDESCR and its method DESCRIBE_BY_OBJECT_REF. The resulting object will have an attribute ATTRIBUTES, which is an internal table, that holds all the information about the attributes of the object reference you've passed to DESCRIBE_BY_OBJECT_REF.

best regards,

Hans Hohenfeld

5 REPLIES 5
Read only

Former Member
0 Kudos
442

Hi,

I'm not entirely sure which way to solve this you prefer. I would add an instance method to the persistence class, which copies the object with the changed key, i.e.

method copy_me importing i_new_key type ...
                          returning value(r_copy) type ref to ZCL_Pers_class.

  data: lo_copy type ref to zcl_pers_class.

  lo_copy = zca_pers_class=>agent->create_persistent( i_key1 = me->key1
                                                                   i_key2 = me->key2
                                                                   i_key3 = i_new_key ).
 
  lo_copy->set_field1( me->field1 ).
 ....

 r_copy = lo_copy.

endmethod.

of course with some error handling, but I guess you'll get that right yourself

If the persitence class has lots of fields, and you are to lazy to type/c&p, you can fill the copied object, by looping over all non key fields and building tzhe setter methody dynamically (use cl_abap_structdescr for that)

best regards,

Hans Hohenfeld

Read only

0 Kudos
442

Its not a matter of not wanting to code/copy all the setters in.

I just think it is bad form to create a method that would need maintenance if/when the underlying attributes are changed.

In the absence of a canned soultion, we had thought of a solution similar to what you suggest. I had considered implementing an interface within our application that has a copy_with_new_date method.

We could loop through the keyed attributes, overwriting the begda to create the new objects, and...

loop through the non keyed attributes to copy the additional values.

That works.

I am not very familiar with the CL_ABAP_xxxDESCR classes .

How, given a class such as ZCL_MYWIDGET, or local object, lo_widget, does one return the list of attrbutes. I've tried a number of combinations, but can't figure it out.

...Mike

( By the way, our object has both persistent and non-persitent values)

Read only

Former Member
0 Kudos
442

Hi,

if you do not want to change the method every time, the persitence class' attributes change, use CL_ABAP:STRUCTDESCR as follows:

data: lo_descr type ref to cl_abap_structdescr,
        lo_type type ref to cl_abap_elemdescr.
  
data: lt_params type abap_parmbind_tab,
        ls_param  type abap_parmbind.

  data: l_method type string,
        l_param  type string,
        l_type   type string.
       

field-symbols: <ls_component> type abap_compdescr,
                     <l_comp> type any,.

" use the name of the table/view/structure corresponding to your persistence class here
lo_descr ?= cl_abap_structdescr=>describe_by_name( 'NAME_OF_STRUCTURE' ).

loop at lo_descr->components assigning <ls_component> where name <> .... "fields you do not want
                                                                                " to copy

  assign me->(<ls_component-name>) to <l_comp>.

  if sy-subrc = 0.
     " get type of the attribute
      lo_type ?= cl_abap_elemdescr=>describe_by_data( <l_comp> ).
      l_type = lo_type->get_relative_name( ).

      " build method and parameter
      concatenate 'SET_' <ls_struct_comp>-name into l_method.
      concatenate 'I_'   <ls_struct_comp>-name into l_param.

      " build parameter table for dynamic method call
      create data ls_param-value type (l_type).
      get reference of <l_comp> into ls_param-value.
      ls_param-name = l_param.
      insert ls_param into table lt_params.

     " call setter method of coppied object dynamically
      try .
          call method lo_copy->(l_method)
            parameter-table
              lt_params.
        catch cx_root.
         " handle errors somehow
      endtry.
  endif.

    refresh lt_params.
    clear   ls_param.
endloop.

It might seem a bit complex at first sight, but works like a charme. I created a class in the system which holds some helper methods, I can reuse to fill a persistence object from a filled structure or fill a structure from the persistence object and so on...

best regards,

Hans Hohenfeld

Read only

Former Member
0 Kudos
443

just in case, if you do not want to work with the structure name as in the above example, you can also use the class CL_ABAP_OBJECTDESCR and its method DESCRIBE_BY_OBJECT_REF. The resulting object will have an attribute ATTRIBUTES, which is an internal table, that holds all the information about the attributes of the object reference you've passed to DESCRIBE_BY_OBJECT_REF.

best regards,

Hans Hohenfeld

Read only

0 Kudos
442

Thank you Hans.

Your answers have been appreciated. The last part about cl_abap_objectdescr=>describe_by_object_ref was quite helpful, as I needed to go after the attributes specifically.

Thanks...

...Mike McInerney