Bug #10258
OO: ON WRITE buffer issue
100%
History
#1 Updated by Teodor Gorghe about 1 year ago
There is an issue about using OO ON WRITE trigger with a buffer.
ABL code:
BLOCK-LEVEL ON ERROR UNDO, THROW.
USING support.test.AssertExt FROM PROPATH.
USING OpenEdge.Core.Assert FROM PROPATH.
CLASS tests.oo.basic.TestOOBufferTrigger:
DEFINE VARIABLE lWrite AS LOGICAL NO-UNDO.
ON WRITE OF tstcasesdb.customer
DO:
lWrite = TRUE.
END.
@Test.
METHOD PUBLIC VOID TestTriggerWrite():
Assert:IsFalse(lWrite).
CREATE customer NO-ERROR.
AssertExt:NotErrorNotWarning().
customer.customerAddress = "asdasdasdas" NO-ERROR.
AssertExt:NotErrorNotWarning().
DELETE customer NO-ERROR.
AssertExt:NotErrorNotWarning().
END METHOD.
END CLASS.
Converted code:
public class TestOobufferTrigger
extends BaseObject
{
Customer.Buf customer = RecordBuffer.define(TestOobufferTrigger.class, Customer.Buf.class, "tstcasesdb", "customer", "customer");
@LegacySignature(type = Type.VARIABLE, name = "lWrite", dataType = "LOGICAL")
private logical lWrite = TypeFactory.logical();
Customer.Buf customerBuf2;
@LegacySignature(type = Type.EXECUTE)
public void __tests_oo_basic_TestOobufferTrigger_execute__()
{
onBlockLevel(Condition.ERROR, Action.THROW);
{
RecordBuffer.openScope(customer);
registerDatabaseTrigger(DatabaseEventType.WRITE, Customer.Buf.class, TriggerBlock0.class, TestOobufferTrigger.this);
}
}
...
public class TriggerBlock0
extends DatabaseTrigger<Customer.Buf>
{
@Override
public void write(final Customer.Buf customerBuf2)
{
trigger(new Block()
{
public void body()
{
RecordBuffer.openScope(customerBuf2);
TestOobufferTrigger.this.customerBuf2 = customerBuf2;
lWrite.assign(true);
}
});
}
}
}
As you can see, there is a field, called customerBuf2, which is null. The problem is that BufferManager.resolvePendingBufferClasses has a list of fields obtained by reflection, including this one, which tries to access it (b.buffer(), line 1025).
One easy fix for this problem is a null check.
#2 Updated by Constantin Asofiei about 1 year ago
Please check how the ON WRITE trigger is converted in a .p in FWD and also the NPE stacktrace.
Please test if this trigger can be executed from both static and instance 4GL class methods
#3 Updated by Teodor Gorghe about 1 year ago
On procedures, the ON WRITE trigger works. It gets converted the same as a OO class.
You can't use record buffers in a static OO class.
Ambiguous runtime method call. Could not resolve TriggerClass reference. (13844).ABL code:
- TriggerClass.cls
USING OpenEdge.Core.Assert FROM PROPATH. BLOCK-LEVEL ON ERROR UNDO, THROW. CLASS TriggerClass: ON WRITE OF adaptivept10 DO: DISPLAY "Called!" adaptivept10.f1. END. METHOD PUBLIC VOID callInstance(): CREATE adaptivept10. adaptivept10.f1 = 1. RELEASE adaptivept10. FOR EACH adaptivept10: DELETE adaptivept10. END. END METHOD. END CLASS. - p-test-trigger-2.p
DEFINE VARIABLE oInstance AS TriggerClass. oInstance = NEW TriggerClass(). oInstance:callInstance().
The conversion is the same: Conversion
On FWD, the difference which makes the OO triggers to not work is that for a OO class, the ObjectOps.newInstance gets called, which will go into BufferManager.resolvePendingBufferClasses.
#5 Updated by Teodor Gorghe about 1 year ago
- Assignee set to Teodor Gorghe
- Status changed from New to WIP
Created task branch 10258a.
#6 Updated by Teodor Gorghe about 1 year ago
- Status changed from WIP to Review
- % Done changed from 0 to 100
Committed revision 16029 on task branch 10258a:
- Fix for OO buffer trigger block.
#7 Updated by Constantin Asofiei about 1 year ago
- Status changed from Review to Internal Test
10258a/16029 looks good.
#8 Updated by Constantin Asofiei about 1 year ago
- Status changed from Internal Test to Merge Pending
Please merge 10258a after 9450a.
#9 Updated by Teodor Gorghe about 1 year ago
- Status changed from Merge Pending to Test
Branch 10258a was merged to trunk revision 16038 and archived.