on 08-08-2018 9:16 AM
The issue is happening within the context of Badi development for SAP BPC.
In the method of the Badi where we can develop our code, we use an exising
standard SAP class (which is CL_UJO_WRITE_BACK) to save data to the
database. We create an instance of that class, and call a method passing some
parameters. Within that method an attribute of the class is updated. Somehow, it
also updates the attribute of the calling instance.
I will explain this again schematically :
Class X , Instance Xa
Instance Xa holds attribute y
Instance Xa calls method which calls a Badi.
In the Badi method, Instance Xb is created of
the same class. Attribute y is updated in method of
Instance Xb. Somehow, it also updates attribute y
of Instance Xa.
Is this the normal behaviour of Abap objects ?
Works as documented.
https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/abapprivate.htm?file=abapprivate.htm
The smallest encapsulation unit of ABAP Objects is the class, not the object.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes, unfortunately this is a normal behaviour of ABAP Objects.
A private attribute of an instance of class X can be changed by every other Instance of class X.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Suhas,
I am also disappointed but try this:
REPORT z_demo.
CLASS lcl_oo_violation_demo DEFINITION.
PUBLIC SECTION.
METHODS:
constructor,
violate_basic_oo_principles IMPORTING ir_oo_violation TYPE REF TO lcl_oo_violation_demo,
get_state RETURNING VALUE(rv_state) TYPE string
.
PRIVATE SECTION.
DATA:
mv_state TYPE string
.
ENDCLASS.
CLASS lcl_oo_violation_demo IMPLEMENTATION.
METHOD constructor.
mv_state = 'initial'.
ENDMETHOD.
METHOD violate_basic_oo_principles.
ir_oo_violation->mv_state = 'changed by someone'.
ENDMETHOD.
METHOD get_state.
rv_state = mv_state.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
DATA:
lr_source TYPE REF TO lcl_oo_violation_demo,
lr_target TYPE REF TO lcl_oo_violation_demo
.
CREATE OBJECT lr_source.
CREATE OBJECT lr_target.
WRITE: / lr_target->get_state( ).
lr_source->violate_basic_oo_principles( lr_target ).
WRITE: / lr_target->get_state( ).
In the method violate_basic_oo_principles you are changing the attribute MV_STATE of the instance LR_TARGET which is of type lcl_oo_violation_demo. I don't see how this violates the OO principle.
I can do the same in Java too.
public class oo_violation {
private String state;
public String getState() {
return this.state;
}
public oo_violation() {
this.state = "I am initial";
}
public void changeState( oo_violation anotherInstance ) {
anotherInstance.state = "I have been changed";
}
}
class Demo {
public static void main(String args[]) {
oo_violation source = new oo_violation();
System.out.println("Source State: " + source.getState());
oo_violation target = new oo_violation();
source.changeState(target); // Change the state of the Target Instance
System.out.println("Target State: " + target.getState());
}
}
You claimed, that it violates basic OO principles, not me!
"
A private attribute of an instance of class X can be changed by every other Instance of class X.
It is not true, unless:
Otherwise it would violate basic OO principles.
"
Attribute mv_state is neither static nor are lr_source and lr_target referencing the same instance.
Btw.: I am pretty sure of C++ not tolerating this (at least the GNU compiler)
A private attribute of an instance of class X can be changed by every other Instance of class X.
Ahh, now i see what you meant by the statement. Sorry for the misunderstanding.
CLASS lcl_x DEFINITION CREATE PUBLIC.
PUBLIC SECTION.
DATA state TYPE string READ-ONLY.
METHODS:
constructor,
main.
PROTECTED SECTION.
PRIVATE SECTION.
DATA: output TYPE REF TO if_demo_output.
METHODS: call_badi.
ENDCLASS.
CLASS lcl_x IMPLEMENTATION.
METHOD constructor.
me->output = cl_demo_output=>new( ).
me->state = |Initial State|.
me->output->write( |State of the current: "{ me->state }"| ).
ENDMETHOD.
METHOD call_badi.
DATA(xb) = NEW lcl_x( ).
xb->state = |Changed in the BAdI|.
me->output->write( |State of the new instance: "{ xb->state }"| ).
ASSERT me->state <> xb->state. " <<< This is what i meant by the violation >>>
ENDMETHOD.
METHOD main.
me->call_badi( ).
me->output->write( |Current State: "{ me->state }"| ).
me->output->display( ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
NEW lcl_x( )->main( ).
When i said,
It is not true, unless:
This is what i meant -
ASSERT me->state <> xb->state.
I hope this clarifies the misunderstanding.
Anyway i found another interesting thread -> https://archive.sap.com/discussions/thread/3482419
"this is a complicated business logic which is already live for a period of time. I cannot explain this on this forum" - top secret! 🙂
I have written write back badi many times for different systems and never have the issues like you have.
But I never set ls_wb_param-update_audit = abap_false. and disable work status check in my badi - to my mind it's a bad practice in general.
All data written to the cube (by input form, script logic, badi etc) has to be reflected in audit log. Same for work status lock.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
This would be easier to answer if you posted the actual code. Use the "code" button in the editor.
Run in debugger and look at the instance numbers of Xa and Xb. Are they the same?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
15 | |
4 | |
2 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.